jasonette / jasonette-ios Goto Github PK
View Code? Open in Web Editor NEW📡 Native App over HTTP, on iOS
Home Page: https://www.jasonette.com
License: MIT License
📡 Native App over HTTP, on iOS
Home Page: https://www.jasonette.com
License: MIT License
It's so cool , but the page load was very slower, urgent need to improve!
When i started running my app in a production environment, some assets like images started to show up as "url": "//xyz...".
My app is using a Rails back-end and it uses cloudfront in a vanilla way, so I think you may face this in the future. So, it may be a good thing to support url schemes like this, since I believe they are standard. I am not sure if you process the data at this level before rendering, in which case, it may be easy for you to handle it the way a regular web browser would.
It would be convenient to have access to the app's URL scheme through something like $system.url_scheme
(or $env.url_scheme
?). Maybe we can attach more environment attributes to the same namespace going forward.
This is especially useful for running $oauth
category actions for specifying redirect_uri
s, but I can imagine it can be used for other purposes as well.
For example instead of hardcoding options.authorize.data.redirect_uri
like this:
{
"type": "$oauth.auth",
"options": {
"authorize": {
"client_id": "{{$keys.client_id}}",
"client_secret": "{{$keys.client_secret}}",
"scheme": "https",
"host": "api.producthunt.com",
"path": "/v1/oauth/authorize",
"data": {
"redirect_uri": "Jafd071e2f8c043611bd1595c1fdcab83c923781d://oauth",
"response_type": "code",
"scope": "public"
}
},
"access": {
"client_id": "{{$keys.client_id}}",
"client_secret": "{{$keys.client_secret}}",
"scheme": "https",
"host": "api.producthunt.com",
"path": "/v1/oauth/token",
"data": {
"grant_type": "authorization_code",
"redirect_uri": "Jafd071e2f8c043611bd1595c1fdcab83c923781d://oauth"
}
}
},
"success": {
"trigger": "fetch"
}
}
It would be nice to have it replaced with:
{
"type": "$oauth.auth",
"options": {
"authorize": {
"client_id": "{{$keys.client_id}}",
"client_secret": "{{$keys.client_secret}}",
"scheme": "https",
"host": "api.producthunt.com",
"path": "/v1/oauth/authorize",
"data": {
"redirect_uri": "{{$system.url_scheme}}://oauth",
"response_type": "code",
"scope": "public"
}
},
"access": {
"client_id": "{{$keys.client_id}}",
"client_secret": "{{$keys.client_secret}}",
"scheme": "https",
"host": "api.producthunt.com",
"path": "/v1/oauth/token",
"data": {
"grant_type": "authorization_code",
"redirect_uri": "{{$system.url_scheme}}://oauth"
}
}
},
"success": {
"trigger": "fetch"
}
}
Not sure if $system
is better or $env
is better. Or maybe there's a better option. Any suggestion welcome.
So it looks like the plug-in approach #26 will use notifications to communicate with the core. This
opens new possibilities for integrations. For example, issue #49 is about web socket support. Such
a feature can live in a plug-in w/o problems.
However, web sockets are async in nature, that is, they can receive messages at any time. How
would users be able to react on those events?
Note: I use WebSocket as an example here. This is obviously useful for catching other
events and could replace the hard-coded "system events" in Jasonette.
I propose a new action type for events. Those actions would "register" itself for a notification
handler by name:
{
...
{
// register hypothetical web socket
"type": "@JasonetteWebSocketPlugin.connect",
"options": {
"url": "wss://example.com/ws/echo"
}
}
...
// register for events
{
"type": "!WebSocket.message",
"success": {
// do whatever you want here. Will be called on the 'WebSocket.message'
// notification sent by the WebSocket plugin if messages arrive
}
},
...
}
For the above to work, the hypothetical WebSocket plugin would send a notification on received messages with name WebSocket.message
.
The !WebSocket.message
action would instruct the core to register a notification handler for
the WebSocket.message
notification and do a [[Jason client] success:notification.object]
if
the notification is received. This can be nicely done in a block.
All this could be done in a plug-in also. But this ia s feature which is core-worthy IMHO 😄
Hi I just wanted to start this as discussion about the advantages of JSON over HTML. I didn't see a faq or anything that explains why JSON was chosen over the already standard HTML format which is used for effectively the same purpose, except for web development instead of app development.
This brings up a few questions
Just to be clear I'm asking these questions, because I'm not informed enough to understand the reason behind the choice of json over html, not because I think json is worse.
Hi,
This is an amazing thing you're doing here, I wonder if you considered an android port?
Would be the next cross-platform framework that would rule them all 😁
I'm heavy on the HTML5 CSS3 bandwagon and love using SVG graphics for backgrounds as well as icons. Can you give a heads up or documentation on using SVG graphics or how to implement vector graphics so I can get a grasp of it?
I have created a code sample by removing some code (not the correct way) to support multipart HTTP requests for one of my first jsonette apps
The JSON app is like this - it's based on the S3 Upload example, but because the normal upload requires only one request it's simpler, as there is no signign request, the server accepts any requests for file upload at the moment, simple logic
{
"$jason":{
"head":{
"title":"IPFS Upload App",
"actions":{
"$load":{
"type":"$media.camera",
"options":{
"quality":"0.2"
},
"success":{
"type":"$network.upload",
"options":{
"url":"https://localhost:3000/ipfs_add",
"method":"post",
"content_type":"image/jpeg",
"data":"{{$jason.data}}"
},
"success":{
"type":"$render"
}
}
}
}
},
"body":{
"sections":[
{
"items":[
{
"type":"label",
"text":"Image uploaded"
},
{
"type":"label",
"text":"Refresh",
"action":{
"type":"$reload"
}
}
]
}
]
}
}
}
code in my fork that works with the client code:
develop...makevoid:simple-upload-sample-code2#diff-8da86b4d62074b49c79b7262005abd78R458
(not the ideal implementation - just for sample)
the server just reads the body and saves it locally so you can verify that the file has been uploaded
2 messages from jasonette slack
@gliechtenstein : ...instead of the current code where it uses https://github.com/Jasonette/JASONETTE-iOS/blob/develop/app/Jasonette/JasonNetworkAction.m#L45
@gliechtenstein : ....the only difference would be these lines
so, look at the additional attribute for $network.request, and if we need to upload, then we use the POST:constructingBodyWithBlock
instead of POST:parameters:progress
and leave the $network.upload
reserved for all advanced upload requests that involve not just uploading but also getting signed urls (for any cloud services, not just s3, but maybe azure, dropbox, etc.)
I +1 this for a standard implementation that supports a custom upload, maintains the s3 implementation which is cool but also some doc will be good for other providers/implementations like rackspace, drobpox, box, mega, hubic, sync, drive, ipfs, torrent, spideroak, etc maybe as cocoapods plugins in the future...
The current behavior shows that the app is aware of when it loses connectivity. It displays a small green notification (should be orange or red-ish, incidentally, since it's bad news).
But it should do a little more, in my view. I do notice that some views (notably if the main url is not accessible) just display an empty page with nothing on them. I think there should be an image or some text that could be configurable in the app for the app developer to add, as a default.
Very cool project!
Could you add an explicit LICENSE file to the repository? I see that you've mentioned that the project is MIT licensed at the end of the README. Still would be helpful to include it as a separate explicit LICENSE file. One benefit is that Github will detect the license and display it at the top of the repository page.
Keep up the great work!
One thing that may become handy over time would be to refer to some resources as local to the app, including: json, images, audio file, etc.
For some apps, the benefit of being local means
This is not a requirement for me at the moment, but it may be worthwhile to explore. You could use a "file://....." path or something if that works, or even something special like "app-local://...."
PS: All that coupled with some smart caching, it could make apps even usable (partially or even fully) without network in some cases. But that's another topic altogether.
it would be useful to be able to manage the badge on the icon
http://stackoverflow.com/questions/4861131/updating-ios-badge-without-push-notifications
use case: the app retrieve blog posts and display the number of unread posts
I'm not a programmer, would it be possible ?
I recommend that Jasonette supports config files in the hjson format ( http://hjson.org/ )
This would demand a parsing of the config file after downloading it before using it as its used today.
Pure JSON would still work, but errors like an extra ,
after last element in an array would not spoil it all.
Another plus is that the developer can have comments in the config file and comment whole sections out (not possible with JSON)
Update: Inspired by http://nshipster.com/javascriptcore/ I have a feeling it could be implemented without much fuzz with JavaScriptCore
let configfileContent = sameWayToFetchFileAsToday();
do {
let hjsonSrc = try String(contentsOfFile: 'path/to/hjson.js', encoding: NSUTF8StringEncoding)
} catch let error as NSError { print("Error: \(error)") }
let context = JSContext()
context.evaluateScript("var hjson2json = function(hjson){ return JSON.stringify(Hjson.parse(hjson), null, 4); };")
let hjson2json = context.objectForKeyedSubscript("hjson2json")
let configJson = hjson2json.callWithArguments([configfileContent])
You might want to use the hjson.js file from http://hjson.org/js/hjson.js where its already "browserified".
I see scroll behavior in items that is not as “smooth” as native. There is a little bit of jerkiness when scrolling. You can see it in the View > Sections area of Jasonpedia with the Jason app.
Please disregard the first time that it loads, as it clearly has to load images, maps, etc. After it has loaded, it still has a distinct "jerkiness" to it that you typically not see in native apps (mail, duck duck go ios app, etc.), even when scrolling somewhat slowly.
My app has a header, footer and one section with a bunch of items, typically a dozen or so, 6 showing at a time. Every app will improve if the framework is smooth at scrolling.
This is really quite a brilliant idea and well executed. Would you ever consider doing the same for android?
Something like that:
"templates": {
"body": {
"sections": [
{
"items": {
"{{#each $jason}}": {
"type": "label",
"text": "{{article.title}}",
"href": {
"param-to-pass-data": "{{article}}",
"template": "article",
"view": "jason"
}
}
}
},
]
},
"article": {...}
It would display another view in a push transition. Data can be passed.
My use case behind: I have everything I need in the first $network.request (a json with a list of articles, with their body). So I don't need extra http call, etc.
First talk was on slack. Need discussion.
Update Setup
command to display url scheme
and oauth redirect uri
.
This is an enhancement to Jason to accommodate a more powerful event system.
The current system allows you to respond to only a default event
which is quite limiting.
What I propose is to add an events
field. This will be an array
of events
with their corresponding actions.
This does not supersede the current implementation as the default action
field will still remain and behave as expected. This new addition will only be for advanced usage.
This enhancement should support existing action mechanisms including inline actions
, trigger actions
and href actions
.
Spec Considerations
action
and href
should can be used to respond to an eventunderscore_case
development
mode and reporting them in production
.Examples
{
"type": "label",
"text": "Refresh",
"action": {
"type": "$util.banner",
"options": {
"title": "Default action",
"description": "This is a default action"
}
},
"events": {
"click": {
"type": "$util.banner",
"options": {
"title": "Event action",
"description": "This is an event action"
}
}
}
}
{
"type": "label",
"text": "Refresh",
"action": {
"trigger": "refresh_view"
},
"events": {
"click": {
"trigger": "refresh_view"
}
}
}
{
"type": "label",
"text": "Refresh",
"action": {
"href": {
"url": "https://www.twitter.com/gliechtenstein",
"view": "web"
}
},
"events": {
"click": {
"href": {
"url": "https://www.twitter.com/gliechtenstein",
"view": "web"
}
}
}
}
{
"type": "label",
"text": "Refresh",
"events": {
"click": {
"type": "$util.banner",
"options": {
"title": "Event action",
"description": "This is an event action"
}
},
"change": {
"trigger": "refresh_view"
}
}
}
If you want fancy a quick laugh, check out CocoaPods/CocoaPods#6158
{
"$jason": {
"head": {
"data": {
"posts": [
{
"title": "title1"
},
{
"title": "title2"
}
]
},
"templates": {
"sections": {
"{{#each posts}}": [
{
"items": [
{
"components": [
{
"type": "label",
"text": "{{title}}"
}
]
}
]
}
]
}
}
}
}
}
should add: iPhone 7plus, IOS 10.1, "develop" branch
See this example where some (top 3, not all, interestingly) images in a list get distorted.
http://dl.dropbox.com/u/364883/Screenshots/fj-3.png
one can get rid of the artifacts by scrolling down and then up.
this is not too easy to reproduce yet, but i see it upon returning back to the app after a little while, typically after going to sleep.
Is there any in app purchase plugin in somewhere?
Hey there,
I was thinking about how to speed up navigation and remembered the case where some flickr pictures were getting deleted because some browsers where prefetching links. But, flickr had implemented DELETE
as GET
… ¬_¬ lovely!
Anyway, these days HTML supports adding prefetch
(and the likes) hints to the browser so it speeds up certain aspects of the navigation.
As part of that, there's also lazy loading images (which could be its own separate GH issue)… A quick search in this repository gave me a couple of hints that the library we're using to render images already support it (?).
{
"type": "html",
"text": "<audio src=\"https://s3.amazonaws.com/www.textcast.co/icons/yo.mp3\">ERROR</audio>"
}
Yields ERROR, it appears that it's not using html5 rendering.
There are some features you can only use in your apps once you enable from XCode's "capabilities" tab. This includes push notification, iCloude, Apple Pay, In app purchase, etc. Here's what it looks like in XCode:
Currently we have two features that requires turning on capabilities--Map and Push Notifications. For maps, turning it on doesn't make a huge difference.
However for most other capabilities--including push notifications--it's not that simple. When you turn on a push notification feature, it adds an "entitlements" file to the project. But that's not all. I think there are more things going on behind the scenes than just this entitlements file.
As an example, see this part (where it says "In your developer account, the Push Notifications service will appear as Configurable (not Enabled) until you create a client SSL certificate."):
If I'm interpreting this correctly, we can't just turn on these capabilities in the master branch and distribute it as open source because turning it on in XCode is not just a matter of adding a new file or setting a config, but it actually changes the things on the Apple developer account backend side.
We could just keep these turned off and let people turn them on only if they want to implement them. And I think that's totally a fine approach. For example, have push notifications turned off by default, and let people enable them through XCode.
The problem is, even with the capabilities are off there's still push related code in there (such as registering for notification and acquiring device token etc.), so when you submit to the appstore, Apple gives you an error saying that you need to either:
This is confusing for users #25 (comment) and I think we need to fix this before merging to master.
I've been researching this and asking around but couldn't find a clean solution. Maybe there's a way to conditionally compile/build code depending on which capabilities to support, so the push related code will not be included in the final build if people don't implement push? Anyone know how to deal with this type of problem?
The built-in template parsers are responsible for parsing different types of data with a template expression written in JSON. Here's an example template for parsing JSON:
{
"{{#each $jason.items}}": {
"type": "label",
"text": "{{title}}"
}
}
There are currently four parsers: CSV
, HTML
, JSON
, RSS
. All template parsers are written in Javascript. It's because:
Currently these files are compiled using Browserify before being added to the project, so it's not so readable and not versionable), which makes it impossible for anyone to contribute. Will need to extract these JS files out into their own repos soon, along with tests.
with a templates.body.header.title = "{{$json.foo}}"
where foo is { "foo": "hello" } returned by the on load handler
while the data is still being fetched, the title shows as "{{$json.foo}}" then when loaded turns into "hello"
The "$jason" > "head" property (I don't know the terms for these entities, sorry) contains a property named actions. It describes events that Jasonette handles. I suggest the name for this property be restored to events. This is more in line with standard terminology and reduces confusion with the term action, which is of course the code triggered by an event. So it would look like this:
"$jason": {
"head": {
"events": {
"refresh_view": {
"type": "$network.request",
"options": {
"url": "https://jasonbase.com/things/jYJ.json"
},
"success": {
"type": "$render"
}
}
},
...
}
As discussed in #26 we need some solution for managing and sharing extensions outside of the
main GH repo.
Let's try to get a cocoapods enabled simple example action going.
Hello,
I am looking at this and i must say, i am pretty impressed.
My questions(a lot of people could have the same questions):
Is this production ready? Can you actually make an entire app on jasonette?
If i am creating a large application, wont the performance hurt?
Thanks!
I built an app with Jasonette in one day (yay!). But am now having trouble submitting it to the App Store due to provisioning issues? See attached image. What's weird is that my Jasonette XCode project is /not/ in my Applications folder, like this popup says. I've also followed most of the stack overflows to due with this error and am still getting nowhere. Just wondering if this is something you've come across.
It would be nice to have the ability to control input fields a bit, kind of like secure
for password fields, but more general, for these types (sort of like html5 field types).
secure
inside style
)perhaps one day down the road you could have touch id and other kinds.
not a high priority, since there is a decent alternative. just a nice to have.
Great project!
What about push notifications?
at the moment it appears to be shown when using replace, so the user can go back to the previous view.
Need help
Currently it's not so easy to debug when something fails.
@seletz added a JasonLogAction so we can call actions like "type": "$log.debug"
to see things on the XCode console, and I think that's a great first step.
But still it's hard to debug things when something goes wrong. I can think of a couple of solutions.
One is, maybe implement some sort of JasonAnalyticsAction
, which can send messages to whichever analytics service users want specify (like Heap, Sentry, Mixpanel, Google Analytics, etc)
Example:
{
"type": "$network.request",
"options": {
"url": "...",
"method": "post"
},
"success": {
"type": "$render"
},
"error": {
"type": "$analytics.send",
"options": {
"provider": "mixpanel",
"data": {
"message": "{{$jason}}"
}
}
}
}
In order for this to be possible, we need to:
Or another option would be we could create a separate extension class to handle each analytics service.
But anyway, there can be other ways to do this, so feel free to make suggestions. This is really a pain point for a lot of people (especially the people who normally don't use XCode much) and even myself because it's such a hassle to step through each line and find out what's going on.
i think for safety reasons, there should be an option (possibly default enabled, if you ask me!) to not show or enable the url box, much less let the user interact with it.
a simple "Done" should suffice in the header, i think.
I noticed that the edit/compile/test cycle when working on real devices is abysmally slow even on my maxed out MB Pro.
The build seems to use the most time in the "custom build scripts".
As discussed in slack, the idea would be to have a timeout on the $network.request
action.
use case: tap tab bar item to open camera
{
"image": "https://raw.githubusercontent.com/Jasonette/Twitter-UI-example/master/images/home.png",
"text": "Create Payment",
"style": {
"height": "21"
},
"url": "https://raw.githubusercontent.com/Jasonette/Twitter-UI-example/master/moments.json",
"href": {
"view": "PaymentViewController"
},
"action": {
"type": "$util.alert",
"options": {
"title": "Good job!",
"description": "You know how to press a button!"
}
}
}
When adding a component, I'd like to be able to set the alpha of that component using the "background" key with a valid RGBA value. At the moment, if I set the 'A' value to anything besides 0, it will color it fully, without opacity.
This is not the only use case, but it was the one which made me post this issue: it would be really useful to have websockets support so we can do "live-reload" during development.
From HN:
@blairanderson 1 hour ago [-]
I would recommend adding documentation for shipping to the App Store.
Even if it's as simple as "just build and submit".
Now that people contribute and start to develop extensions for actions and other things
in Jasonette, we begin to see problems w.r.t. the extension development workflow.
This issue intends to kick off a discussion on the following and other related topics.
XCode Project Issues
As soon as more than one developer works in the main repository, changes in the XCode project files start to become an issue. While these files are text files in principle, merging them is a PITA.
Also it's not immediately clear what changes should be merged.
Extension Maintenance
While the current practice of adding code to the main line of Jasonette is probably OK for now,
not all extensions people come up with are useful or generic enough to warrant a inclusion in the
main line of Jasonette.
"Pull to refresh" taking up the top space and not fully going all the way back.
support url scheme like appname://url/https://jasonbase.com/things/fen.json
, and it opens that particular url
Hi,
Feature idea.
When opening a web browser view ("view":"web"
), an option to open Safari with the reader mode.
That's an option given by SFSafariViewController.
Any plans to open a repo where people can contribute with code to an drag-and-drop kind of editor of the JSON for Jasonette?
Some people have requested local JSON feature. I have some concerns on this. But I also see some benefits. And overall, I think it's worth discussing.
There can be two solutions to this:
Just use the internal method to directly open a JSON file from the bundle and draw it to the view.
Set up an in-app web server and serve local files through the web server. (You could access them using something like local://
or localhost://
or something like that) This may sound convoluted compared to Approach 1, but I think it's interesting in its own way. More on this below.
There have been a couple of pull requests for this. I took a look at them and categorized them into these categories:
Approach 1
Approach 2
The obvious benefit is you can run your app offline. This is great, and some people have asked for this. Also you can quickly develop locally if you have a local JSON.
My concern is just that I wasn't envisioning this kind of usage when I was building Jasonette. It may look like just an innocent little feature, but I think it may have larger implication than that, going forward.
Until now Jasonette has been fully cloud based, therefore easy to understand--You simply add a URL and you have an app.
However once we support this, we have no reason not to support all kinds of other offline features. So it's not just a matter of "let's add this little feature", we will need to commit to this direction. With the current thin client approach, we can easily scale to other platforms since everything is cloud based, but starting to support local may mean this may be difficult. (Then again, even desktop web browsers have localhost features, so maybe it's workable, i don't know) But this is just my opinion based on my gut feeling. That's why I would love to hear thoughts.
I do think we may need to support this local feature at some point. It's just a matter of whether we should do it now or not. What are your thoughts on "support local now" vs. "think about it later"? Maybe it's worth a try to support it now and see how it goes?
The web server approach by @copongcopong caught my interest because this feels like it could enable many other types of usage for Jasonette. Serving local files is just one usage, but what excites me is when you have a web server running, you can serve to the outside world as well. I like to imagine things so I could think of some weird and exciting use cases. I don't know yet what this would mean but I feel like there's something there. Any thoughts on this?
For example, this Jason will result in 404 for the linked page because # is not decoded on the webview
{
"type": "label",
"text": "Visit Website",
"href": {
"url": "http://simplydo.com/cryptography/#/about",
"view": "Web"
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.