1 00:00:00,000 --> 00:00:03,000 [Jim Hoskins] So now we have a pretty cool mobile application 2 00:00:03,000 --> 00:00:06,000 that can save Notes, save locations to Notes, 3 00:00:06,000 --> 00:00:09,000 get you a list of your Nearest Notes, and so on. 4 00:00:09,000 --> 00:00:13,000 Now, what's really going to be great is if we can use this offline. 5 00:00:13,000 --> 00:00:17,000 Right now, it is always requesting the latest code from the server, 6 00:00:17,000 --> 00:00:21,000 but if we're not connected to the server, it would be nice if the application still worked. 7 00:00:21,000 --> 00:00:24,000 After all, it doesn't need a server to store data, 8 00:00:24,000 --> 00:00:28,000 so if I'm offline, why should the application not be available? 9 00:00:28,000 --> 00:00:31,000 Let's see what would happen if I turn off Web Sharing, 10 00:00:31,000 --> 00:00:35,000 which is right now what's controlling my Apache web server in development. 11 00:00:35,000 --> 00:00:38,000 So we turn that off and I refresh, 12 00:00:38,000 --> 00:00:41,000 we cannot connect to localhost because our web server is not running. 13 00:00:41,000 --> 00:00:46,000 What I want to happen is I want to be able to access my application. 14 00:00:46,000 --> 00:00:49,000 So I'm going to turn our server back on-- 15 00:00:49,000 --> 00:00:52,000 it will just take a minute to fire up-- 16 00:00:52,000 --> 00:00:57,000 and if I refresh, we should get our application back like that. 17 00:00:57,000 --> 00:01:03,000 So the way we can do this is utilizing HTML5 offline application storage 18 00:01:03,000 --> 00:01:07,000 and what this is is we will simply create a manifest file 19 00:01:07,000 --> 00:01:12,000 telling the web browser about all the assets needed to run this application. 20 00:01:12,000 --> 00:01:15,000 Then, when it gets them, it will cache them away, 21 00:01:15,000 --> 00:01:19,000 and if it's unable to reach the server, it can use those cached files. 22 00:01:19,000 --> 00:01:23,000 Now, the best online documentation I found from this 23 00:01:23,000 --> 00:01:29,000 is from the Dive Into HTML5 book.diveintohtml5.org/offline.html 24 00:01:29,000 --> 00:01:32,000 Now, it's a huge subject--this goes into how everything works-- 25 00:01:32,000 --> 00:01:37,000 and the best way to manage your cache, including a few gotchas 26 00:01:37,000 --> 00:01:41,000 that you really, really want to take care of. 27 00:01:41,000 --> 00:01:47,000 So first, let's go ahead and try to create our cache manifest file. 28 00:01:47,000 --> 00:01:57,000 Now to do that, we will create a new file in our directory called cache.manifest. 29 00:01:57,000 --> 00:02:02,000 Now, how this works is it will start off with the lines CACHE MANIFEST 30 00:02:02,000 --> 00:02:08,000 and any lines that begin with a # will be a comment 31 00:02:08,000 --> 00:02:20,000 so what we're going to do is we're going to comment of #Cache Manifest rev: 1. 32 00:02:20,000 --> 00:02:25,000 The reason I'm giving a revision number here is because the application will only try to fetch 33 00:02:25,000 --> 00:02:31,000 the newest contents if the cache manifest has changed. 34 00:02:31,000 --> 00:02:35,000 Now, this is important because when we're developing or deploying new information, 35 00:02:35,000 --> 00:02:39,000 we may want to tell the browser to recache all the assets. 36 00:02:39,000 --> 00:02:45,000 However, the actual values in our cache manifest file might not change. 37 00:02:45,000 --> 00:02:50,000 So one way we can change the file is to change a comment every time we update our files. 38 00:02:50,000 --> 00:02:57,000 So then, the way it works is we can have a CACHE line with a colon 39 00:02:57,000 --> 00:03:05,000 and every file we list here--like index.html, css/main.css-- 40 00:03:05,000 --> 00:03:10,000 every one of these files, when the page loads, will be cached away. 41 00:03:10,000 --> 00:03:16,000 Now, there's always a different header we can give of NETWORK: 42 00:03:16,000 --> 00:03:18,000 The section under this will never be cached, 43 00:03:18,000 --> 00:03:21,000 and this is important, especially since we're using Google Maps, 44 00:03:21,000 --> 00:03:25,000 which we can't cache and we wouldn't want to have it actually try to cache. 45 00:03:25,000 --> 00:03:30,000 So what we will do is we'll say you always need to use a network 46 00:03:30,000 --> 00:03:33,000 for the Google Maps. 47 00:03:33,000 --> 00:03:38,000 So the tricky part here is we need to actually get all of our files 48 00:03:38,000 --> 00:03:40,000 into this cache section. 49 00:03:40,000 --> 00:03:43,000 Now, one way we can do this is to use the Terminal 50 00:03:43,000 --> 00:03:48,000 and use a little bit of text editor magic to try to streamline this for us. 51 00:03:48,000 --> 00:03:52,000 We could go through each of our files, but since we have several JavaScript files 52 00:03:52,000 --> 00:03:58,000 and several CSS files and icons included with jqjQuery Mobile, 53 00:03:58,000 --> 00:04:01,000 it's going to be a long process to manually type in 54 00:04:01,000 --> 00:04:04,000 each and every file associated with our project. 55 00:04:04,000 --> 00:04:07,000 So what we can do is from our web directory here, 56 00:04:07,000 --> 00:04:12,000 we could type in $ls for listing - l for the long form 57 00:04:12,000 --> 00:04:16,000 and capital R for recursive, and what this will do 58 00:04:16,000 --> 00:04:19,000 is it will print out all of our files in all of the subdirectories 59 00:04:19,000 --> 00:04:21,000 of this current directory. 60 00:04:21,000 --> 00:04:27,000 We're going to go ahead and edit that output in order to create our cache.manifest file. 61 00:04:27,000 --> 00:04:31,000 So here we can see each of our different directories here, 62 00:04:31,000 --> 00:04:38,000 and what I'm going to do is I'm just going to try to copy this all out 63 00:04:38,000 --> 00:04:44,000 and I'm just going to paste it into our cache section here 64 00:04:44,000 --> 00:04:49,000 and we get the output of all of our files in here. 65 00:04:49,000 --> 00:04:52,000 So now we just need to go ahead and clean this up. 66 00:04:52,000 --> 00:04:54,000 Now, depending on how good you are with macros and stuff, 67 00:04:54,000 --> 00:04:56,000 you can probably do this a lot faster, 68 00:04:56,000 --> 00:05:00,000 but one thing I like about TextMate is if you hold down the Alt button, 69 00:05:00,000 --> 00:05:03,000 it takes you into a special Block Select mode 70 00:05:03,000 --> 00:05:06,000 where you can select certain columns along certain lines 71 00:05:06,000 --> 00:05:09,000 instead of doing a normal linear select. 72 00:05:09,000 --> 00:05:13,000 So by holding down Alt, my cursor changes into a cross here 73 00:05:13,000 --> 00:05:18,000 and I can just drag from here all the way to this column 74 00:05:18,000 --> 00:05:21,000 because I want to get rid of all of this, 75 00:05:21,000 --> 00:05:28,000 and with this all selected, I can simply hit delete and it's gone. 76 00:05:28,000 --> 00:05:31,000 Now, on this top level, there's really only one file I need. 77 00:05:31,000 --> 00:05:34,000 I don't want to cache the manifest itself. 78 00:05:34,000 --> 00:05:37,000 I don't want to cache the directories--we'll do that in a moment-- 79 00:05:37,000 --> 00:05:40,000 of css and js. 80 00:05:40,000 --> 00:05:44,000 And this total header here I just want to remove. 81 00:05:44,000 --> 00:05:47,000 So we have our index.html. 82 00:05:47,000 --> 00:05:49,000 Obviously, for that section, it would have probably just been faster 83 00:05:49,000 --> 00:05:54,000 to type index.html, but let's just keep on moving along. 84 00:05:54,000 --> 00:05:58,000 So in our CSS directory, we have four files. 85 00:05:58,000 --> 00:06:02,000 In our CSS directory we have three files and a directory. 86 00:06:02,000 --> 00:06:08,000 We don't want this directory because we'll be handling each file in the directory separately-- 87 00:06:08,000 --> 00:06:12,000 I don't want this header line here-- 88 00:06:12,000 --> 00:06:14,000 and by using our block select mode, 89 00:06:14,000 --> 00:06:20,000 I will delete all of that. 90 00:06:20,000 --> 00:06:24,000 I do need to prefix css/ to each of these lines. 91 00:06:24,000 --> 00:06:29,000 I can go ahead and remove this line and replace it with #CSS. 92 00:06:29,000 --> 00:06:33,000 So to add css/ to the beginning here, 93 00:06:33,000 --> 00:06:38,000 what I'll do is hold down Alt to go back to block select mode 94 00:06:38,000 --> 00:06:41,000 and select a column before the first character in here. 95 00:06:41,000 --> 00:06:45,000 You can barely see it, but there is a selection before each line here 96 00:06:45,000 --> 00:06:48,000 and when you have a block selection like that when you start typing, 97 00:06:48,000 --> 00:06:50,000 it will type simultaneously on all lines. 98 00:06:50,000 --> 00:06:58,000 So to add CSS, I'll just type in css/ and we have changed all those files at once. 99 00:06:58,000 --> 00:07:03,000 So this is for css/images, so let's clear that header line. 100 00:07:03,000 --> 00:07:06,000 Let's use block select. 101 00:07:06,000 --> 00:07:08,000 We have that all selected. 102 00:07:08,000 --> 00:07:13,000 If I hit delete, I've lost my selection, but I can grab that again 103 00:07:13,000 --> 00:07:17,000 by just holding Alt and drawing down the left column here. 104 00:07:17,000 --> 00:07:23,000 I'll add in css/images/ 105 00:07:23,000 --> 00:07:27,000 and I can change this into a comment. 106 00:07:27,000 --> 00:07:31,000 I'll do the same for js; remove this header 107 00:07:31,000 --> 00:07:37,000 and I can do this all in one go by just selecting it all, 108 00:07:37,000 --> 00:07:46,000 and instead of hitting delete, I could just type in js/ and we'll go ahead and into a header as well 109 00:07:46,000 --> 00:07:50,000 and that is all of our files. 110 00:07:50,000 --> 00:07:53,000 So now we've created a cache.manifest file 111 00:07:53,000 --> 00:07:55,000 and this should work for us. 112 00:07:55,000 --> 00:07:58,000 Now we need to integrate it into our application 113 00:07:58,000 --> 00:08:00,000 to tell the browser that we have this cache manifest file 114 00:08:00,000 --> 00:08:02,000 and it should be using it. 115 00:08:02,000 --> 00:08:05,000 Now, there's a couple of things you need to do to your server 116 00:08:05,000 --> 00:08:09,000 or you may need to do to your server in order to have cache.manifest work. 117 00:08:09,000 --> 00:08:13,000 One is that a .manifest file should always be served 118 00:08:13,000 --> 00:08:17,000 with the mime type of text /cache-manifest 119 00:08:17,000 --> 00:08:21,000 so what we need to do is tell our server that any .manifest file 120 00:08:21,000 --> 00:08:24,000 should be served with that mime type. 121 00:08:24,000 --> 00:08:26,000 The server may already be configured for this 122 00:08:26,000 --> 00:08:31,000 but if it's not, we need to go ahead and add a line to our Apache configuration file 123 00:08:31,000 --> 00:08:34,000 or whatever server configuration you have set up. 124 00:08:34,000 --> 00:08:37,000 I'm going to show you how to do it on a Mac 125 00:08:37,000 --> 00:08:41,000 using the default Apache install. 126 00:08:41,000 --> 00:08:44,000 Going to our Terminal here, what I could is open up our configuration 127 00:08:44,000 --> 00:08:52,000 by typing in $mate /etc/apache2/mime.types 128 00:08:52,000 --> 00:09:00,000 and here we can see the list of all the mime types we have here. 129 00:09:00,000 --> 00:09:02,000 And so what I'm going to do is at the bottom here, 130 00:09:02,000 --> 00:09:10,000 we'll add our own of text/cache-manifest 131 00:09:10,000 --> 00:09:16,000 and we'll add some space here and we'll say always serve that 132 00:09:16,000 --> 00:09:21,000 when we have a manifest file. 133 00:09:21,000 --> 00:09:24,000 Now, when you save this out, since it is a privileged file, 134 00:09:24,000 --> 00:09:29,000 you may need to give your password in order to save it out 135 00:09:29,000 --> 00:09:34,000 and then you'll need to restart your server. 136 00:09:34,000 --> 00:09:39,000 So let's actually test out if we are getting the cache manifest file served correctly, 137 00:09:39,000 --> 00:09:43,000 so we'll go to cache.manifest. 138 00:09:43,000 --> 00:09:45,000 We can see it is serving 139 00:09:45,000 --> 00:09:50,000 and we can actually see it's interpreting this resource of the document 140 00:09:50,000 --> 00:09:53,000 but it was actually served with text/cache-manifest, 141 00:09:53,000 --> 00:09:56,000 which is exactly what we want. 142 00:09:56,000 --> 00:09:58,000 On this page it shows you can also use an AddType declaration 143 00:09:58,000 --> 00:10:02,000 anywhere in your configuration, or you can do it in the mime.types folder 144 00:10:02,000 --> 00:10:05,000 like we did before. 145 00:10:05,000 --> 00:10:08,000 One last thing you want to do--especially while in development--is to make sure 146 00:10:08,000 --> 00:10:12,000 that the server is not going to cache the cache-manifest itself. 147 00:10:12,000 --> 00:10:16,000 Otherwise, it becomes very, very, very difficult 148 00:10:16,000 --> 00:10:18,000 to get past the cache. 149 00:10:18,000 --> 00:10:22,000 One way you can do this is to create a .ht access file for your Apache server 150 00:10:22,000 --> 00:10:27,000 and set ExpiresActive On and ExpiresDefault to "access" 151 00:10:27,000 --> 00:10:31,000 so it'll clear the cache every time it tries to access the file. 152 00:10:31,000 --> 00:10:39,000 So we can create a new .htaccess file with this information on it 153 00:10:39,000 --> 00:10:43,000 and I'm going to go ahead and just restart the server. 154 00:10:43,000 --> 00:10:47,000 You may not need to, but I like to do that any time I change anything. 155 00:10:47,000 --> 00:10:53,000 Let's go back to localhost here, and the cache manifest will not be in effect yet 156 00:10:53,000 --> 00:10:55,000 because we have not included it in the index.html. 157 00:10:55,000 --> 00:10:59,000 So if we refresh, we're not getting any weird server errors, 158 00:10:59,000 --> 00:11:01,000 which is always a good sign, 159 00:11:01,000 --> 00:11:05,000 and the last thing we want to do is in our index.html in the HTML tag, 160 00:11:05,000 --> 00:11:08,000 we want to define where the manifest is for this application. 161 00:11:08,000 --> 00:11:11,000 So we'll go back to our browser, 162 00:11:11,000 --> 00:11:13,000 open index.html, 163 00:11:13,000 --> 00:11:24,000 In this HTML tag, we will add manifest= and then location of it of /cache.manifest. 164 00:11:24,000 --> 00:11:28,000 Save it out and let's take a look at it in the browser. 165 00:11:28,000 --> 00:11:32,000 So here we can see a lot of debug information here. 166 00:11:32,000 --> 00:11:37,000 We can see the application was found, it's downloading all of these different files, 167 00:11:37,000 --> 00:11:39,000 and it's very important to keep track of this. 168 00:11:39,000 --> 00:11:43,000 If you have a missing file or file that it can't find, 169 00:11:43,000 --> 00:11:46,000 it will actually abort mid-process here and nothing will be cached. 170 00:11:46,000 --> 00:11:49,000 So you need to always make sure that your cache is correct, 171 00:11:49,000 --> 00:11:51,000 pointing to files that it can find 172 00:11:51,000 --> 00:11:55,000 because a single 404 will break the whole cache. 173 00:11:55,000 --> 00:11:57,000 Now, if we refresh, it should still work. 174 00:11:57,000 --> 00:12:02,000 We still have access to all of our localStorage here. 175 00:12:02,000 --> 00:12:06,000 Now, let's go into our server here, turn this off, 176 00:12:06,000 --> 00:12:08,000 and let's refresh. 177 00:12:08,000 --> 00:12:13,000 We refreshed and it is still working just fine. 178 00:12:13,000 --> 00:12:19,000 And add New Note with Some Text. 179 00:12:19,000 --> 00:12:24,000 We can even add our location here and save it out. 180 00:12:24,000 --> 00:12:28,000 You can see our New Note works just fine 181 00:12:28,000 --> 00:12:32,000 and this is all with our Apache server turned off. 182 00:12:32,000 --> 00:12:35,000 We can refresh as much as we'd like 183 00:12:35,000 --> 00:12:40,000 and we will always get this because the browser has all of the files it needs 184 00:12:40,000 --> 00:12:43,000 to serve this application. 185 00:12:43,000 --> 00:12:45,000 Any time you change any of your files, 186 00:12:45,000 --> 00:12:52,000 you would want to update the cache.manifest to have an updated revision number 187 00:12:52,000 --> 00:12:57,000 just so you can change the cache so the browser will get all of the new files that you need. 188 00:12:57,000 --> 00:13:00,000 I usually like to do all the caching stuff right at the end of my application 189 00:13:00,000 --> 00:13:03,000 because it's easier to develop with the cache off, 190 00:13:03,000 --> 00:13:07,000 but you definitely want to do some extensive testing with your cache 191 00:13:07,000 --> 00:13:09,000 to make sure it works. 192 00:13:09,000 --> 00:13:12,000 Now I'm going to turn my server on for one last check. 193 00:13:12,000 --> 00:13:19,000 I'm going to turn on my server. 194 00:13:19,000 --> 00:13:21,000 So if we refresh it, it looks like our app is working, 195 00:13:21,000 --> 00:13:27,000 and now in the act of refreshing it, it should be caching all of the files. 196 00:13:27,000 --> 00:13:32,000 So if we turn off the server once again and refresh-- 197 00:13:32,000 --> 00:13:37,000 cool, it looks like we get the entire application working 198 00:13:37,000 --> 00:13:39,000 even though our server is turned off. 199 00:13:39,000 --> 00:13:45,000 So now we have an offline Geolocation-aware localStorage-based mobile application. 200 00:13:45,000 --> 00:13:49,000 And now our note-taking application has the ability to be run offline 201 00:13:49,000 --> 00:13:51,000 using the HTML5 application cache 202 00:13:51,000 --> 00:13:54,000 and we can add location data to our Notes. 203 00:13:54,000 --> 00:13:57,000 The next step would be to actually take your device out into the real world 204 00:13:57,000 --> 00:14:00,000 and test it using real location data.