Whatever “topic” you are viewing, if you close your web browser it “remembers” right where you left off as if by magic… even if you aren’t connected to the internet! This is perfect if you are in city hall where the internet is problematic, you can find the issues that are important to you. In a grander scheme, think of how that could be useful for other applications!
The app functions equally well on a phone versus a computer - it’s pretty cool. How does it do that? Take your computer window and make it smaller, does it now look like the interface for the phone? It does it based on “screen real estate” not by the device at hand.
The “topics” come from a central server, they aren’t hard coded. We can update them easily from a database at any time. Equally cool is that they are stored in a magical place and accessible even without your internet connection! The site always works, when you are on your farm, inside a subway, anywhere at all! Yet it will always update with the latest and greatest info when your Internet is available.
public class CommunityTopicController extends BaseRestController { protected ERXKeyFilter filter() { ERXKeyFilter filter = ERXKeyFilter.filterWithAttributes(); filter.setUnknownKeyIgnored(true); return filter; } public WOActionResults indexAction() throws Throwable { NSArray<CommunityTopic> entries = CommunityTopic.fetchAllCommunityTopics( editingContext(), CommunityTopic.SORT_ORDER.ascs()); return response(entries, filter()); } }
ERXRest.accessControlAllowOrigin=* ERXRest.allowWindowNameCrossDomainTransport=true ERXRest.allowJSONP=true
$ csh % got a light? got: No match. % make love make: *** No rule to make target `love'. Stop. % man: why did you get a divorce? man:: Too many arguments. % ^How did the sex change^ operation go? Modifier failed.
Languages don't make development enjoyable, it's the framework and IDE that do.
Java is not enjoyable. WebObjects is. If we were writing apps in JSP or J2EE we would not be having near as much fun.
Javascript is no different. It has the same learning curve. Good frameworks make javascript nice.
In Hamburg, 2015, I demonstrated what it is like to develop Enyo apps using an interface builder, etc. To learn more about Enyo I'll list some links for further reading so we can continue to discuss "offline apps" today.
We place our "CommunityTopic" component inside our "Viewer" with this call:
{ name: "communityTopicFetch", kind: "CommunityTopic", onResults: "communityTopicResults" }
It is the last element in "components" of Viewer. It has no content of its own.
There is a method called "search()" defined in "CommunityTopic." To invoke it from our Viewer component we call it by the name we gave it and then call the method
this.$.communityTopicFetch.search();
Searching takes time, it is asynchronous, and it might fail if our Internet connection isn't available. We must handle all that.
Because lawnchair is async, we must put all actions that we want to take place in its callback. This also means that we need to scope "this" and pass in the method we want to call using "enyo.bind"
new enyo.Ajax({url: urlToJson, handleAs: "text"}) .response(this, "processAjaxResponse") // good times .error(enyo.bind(this, function(inSender, inResponse) { // bad times var doResultsMethodBoundToThis = enyo.bind(this, "doResults"); Lawnchair({name : 'db'}, function(store) { store.get("communityTopicsResults", function(obj) { var communityTopicsResults = obj.value; doResultsMethodBoundToThis(communityTopicsResults); }); }); })) .go();
We "get" results that are remembered.
CommunityTopic.processAjaxResponse()
// good times - have strong internet connection processAjaxResponse: function(inSender, inResponse) { inResponse = enyo.json.parse(inResponse); this.doResults(inResponse); var db = Lawnchair({name : 'db'}, function(store) { store.save({key:"communityTopicsResults", value:inResponse}); }); return inResponse; }
We "save" results that we fetched from REST.
Sorry. Not going to demonstrate this. There are a few ways to do this but decided this was outside the scope of this talk. Still, don't worry, I will point you in the direction to find more info about this topic.
Defined: an app that loads without being connected to the Internet.
How fantastic! no need to burden your server with any processing other than the actual management of data. This is scalability beyond our wildest dreams! All the work of creating HTML and managing the User-Interface happens on the client without even talking to the server.
So why is none of the above true?
At the basic level - when do you throw away something and get a new one? It's tough to answer that question. Your dream solution is likely different than mine.
EOF is a cache. It confuses many of us until we learn the way it works. Even if we fetch data from the DB we throw the new results away! That is the default behavior. We can say "setRefreshesRefetchedObjects(true)" when we fetch and then we'll keep the new data.
It's a matter of someone not only making a caching mechanism but us actually learning what they were thinking. We can't assume anything.
Offline app implementations are a powder keg full of hurt feelings and conflicting views. Most of us have no idea because we have not tried to make single page apps and have not tried to cache them for the user.
The creators of Firefox have this to say:
"The previous attempt — AppCache — seemed to be a good idea because it allowed you to specify assets to cache really easily. However, it made many assumptions about what you were trying to do and then broke horribly when your app didn’t follow those assumptions exactly. Read Jake Archibald's Application Cache is a Douchebag for more details."
“Hi, I’m ApplicationCache,” he said, as he reached over to shake Dev’s hand. “I turn your offline experience from sucks-ass, to success. Just one extra file, and bosh! It works. No fuss, no ‘scripting’ necessary.” Yes, he did finger-quotes while saying ‘scripting.’ I’m gritting my teeth at this point, because I know he’s greatly exaggerating his abilities and the others don’t see it. However, if I call “bullshit” on it I’ll seem like the jerk. I’m here to tell you ApplicationCache is a douchebag.
Nolan Lawson calls Safari the new Internet Explorer
That's because Safari has no interest in supporting Service Workers nor IndexedDB. There is a strong difference of opinion on how things should work and what is "broken."
Because App Cache works, that's what we should use today. Here are some great articles to read:
cd /usr/local/etc/nginx sudo cp mime.types mime.types.bk_April_4_2016 sudo vi mime.types << add the following >> text/cache-manifest manifest; sudo /usr/local/etc/rc.d/nginx restart
<html manifest="assets/offline.manifest">
If you really want to warn the user:
if (window.applicationCache) { applicationCache.addEventListener('updateready', function() { if (confirm('An update is available. Reload now?')) { window.location.reload(); } }); }
But what's the rush? Why get in their face?
Every time you want to make sure that new files are downloaded, you should update the version of your manifest with a line like this at the end:
# version 14
This will catch things like images whose filename didn't change but content did.
Your manifest must have a line that looks something like this:
NETWORK: *
Without this, any file not specifically written in your manifest will not be available. Even when you are online, connected, you cannot download the file without specifying with an asterisk that all files not in the manifest can be downloaded when you are connected.
If there is any file in your manifest that is not reachable, the whole App Cache falls flat. It will not cache what it can find, it will cache nothing. Make sure that if you delete or change the name of a file in the manifest then you also correct it in the manifest.
Summary Point #1
Summary Point #2
Summary Point #3
We can finally build apps with the same ease and even better performance. These tools took the spirit of WO and improved upon it. A better mousetrap finally exists.
npm -d install ares-ecosystem-ide ~/node_modules/.bin/ares-ecosystem-ide -b
Space | Forward |
---|---|
Left, Down, Page Down | Next slide |
Right, Up, Page Up | Previous slide |
P | Open presenter console |
H | Toggle this help |