I made a WebApp for an iPad which is supposed to run in an intranet. The app is basically a form, kind of an exam. Some questions has videos (videos are around 20MB size). I've defined my cache manifest as follow:
CACHE MANIFEST
CACHE:
/videos/preg1Calidad.m4v
/videos/preg2Calidad.m4v
The .manifest file content-type header is "text/cache-manifest". The thing is that, as this webapp is supposed to access some webservices to read/write data on a database located in a server connected to the intranet, I need the iPads to be connected to the network. When I add my app to the home screen and a question containing a video is prompted, I can see the video is being fetched from the network (I can see the loading animation next to the WiFi icon) istead of being accessed from the iPad itself.
I've deleted safari's data storage, cache, historial, deleted the app and added again, nothing seems to work. The content-type for the .m4v video I've setted it up to "video/mp4".
So, I've several questions:
How can I know for sure if the files on the .manifest are being cached?
I know some browsers apparently has a maximum size of storage for offline apps, never the less, looking into the apple documentation I haven't seen such a thing. Is there any limitation with iPads on file size? Maybe file types?
I don't know if I'm miss understanding the behavior of the webapp for offline access, the definition of the .manifest file, I've been thinking that it might only work when the device is actually offline (no network connection available, airplane mode maybe) but I thought that defining a file as "CACHE" would do the trick so this file wouldn't be accessed from the network. Shouldn't it behave like that?
I can not start developing this as native app at the moment since its kind in production. If anyone gets an idea on how to fix it quickly, would be great. I've been thinking on add the files to the internal database as base64 or in a javascript varial (as base64 also).
Thanks so much.
Related
I have a small webapp that runs on a server intended for use in a setting without reliable internet access (i.e., the app can't depend on outside resources during production). The purpose of the app is simply to upload image files, read the metadata, and categorize them in the right location on the disk. Up until recently there was no problem with this process, then I noticed that some of the files did not have all of the metadata attached (specifically the creation date). Upon further inspection, it appears that these are files that were shot on my iPhone as HEIC/HEIF photos and uploaded directly to the webpage from the phone.
Due to the design of the webapp, the filename of the uploaded file is shown on the page. Every time an HEIC photo is uploaded it displays the filename as ending in .jpeg.
I've had a hard time finding good documentation on this, but it sounds like the default for the iPhone at this point is to convert HEIC files to jpeg if it looks like they are transferring to a location that may not be able to read them. I guess a website form falls into this category. It also appears that as part of this conversion some of the EXIF data disappears.
So, does anyone know a way to retain the EXIF data? My primary limitation here is that the upload needs to happen through the webapp and that multiple users will be using this. As a result, I can't simply have everyone change their iPhone settings to only shoot jpegs.
In case it matters, the webapp is running on node.js and expressjs.
I have to load a lot of data onto an iOS device with 128GB storage, for use by my app. The data is around 2,000 files of around 40Mb each, total is around 80GB - 100Gb.
I control the iOS device and the load machine/program and the local network they're on, and time is not critically important (if it takes a week to load, that's OK). I can format the data as required to facilitate the load.
I've done some iOS programming, but I'm not sure where to start looking for a solution to this. If you can outline the broad approach to use and which iOS docs to read up on, that's all I need.
Hoping for a solution where I can format the data and write the program, plug the iPad in to the Mac and say 'start loading' and come back when it's done.
We discovered that it is possible to load data one device at a time using iTunes, but that isn't a good answer for us.
We added a 'load data' button into the application. When triggered it loads a configuration file from a hard coded local network address, then retrieves all the data files listed in the configuration file using REST GETs from the local server, storing them into the application /Documents directory.
This is a good approach for us; it is secure, allows multiple devices to load data at the same time, and doesn't need any manual file loading : start the app, press 'load', and wait for it to finish.
I'm building a mobile app using Meteor. To allow for offline usage of the app, I want the app to be able to download a large-ish json file while online, then access the data in the json file, written to MongoDB, while offline.
This works fine. However, in the downloaded json file, there are plenty of references to online images that won't display in the app once the app is offline.
So, I want to be able to download (a selection of) the images referenced in the json file to the app, so that the app can access them even when offline.
(Downloading images could happen in the background for as long as a connection is available.)
There's an implementation of imgCache.js available on Atmosphere, which fails to initialize for me.
I suppose it's theoretically possible to individually load each image to a canvas, save the canvas content to MongoDB, then load the content when needed. Info on some of this is here. But, this feels rather convoluted and, if really feasible, I would expect someone to have done this before with success.
How can I do achieve caching of images for offline use in Meteor?
So, you've probably already read this article about application cache.
If the images are static, you can just include them in the manifest. Be sure you understand the manifest and cache expirations (see the article).
If the images are dynamic, you'll find some techniques to store images in local storage
If that's the case, this may be what you want.
Is it possible to create a UIWebView that has an HTML5 offline appcache pre-populated so that it will work offline even if it is the first time the user is accessing the UIWebView?
If so, how?
I know I can achieve this through other mechanisms, but the above is my first choice. And I'm just plain curious if it's possible.
I'm seeing nothing about it in the documentation.
What you are looking for is two files in your cache folder.
ApplicationCache.db and cache.db
They both reside in Library/Caches/[your bundle identifier] folder for your application, which you have full access. You can add pre populated cache data to you bundle, and simply copy it to caches folder on you app launch.
BTW you can play with them easily, as they are simple, SQLITE db's.
I hope this helps
I think this may reduce to a question of whether you can programmatically write to the UIWebView's cache file (which is to say, whether the UIWebView cache resides within your app's sandbox) – if you can't, then game over. If you can, then it becomes a question of what happens after you drop a pre-populated cache file into place, and whether the UIWebView is "fooled" into thinking that it's already downloaded and cached your HTML5 content.
If you're using the iPhone Simulator to test your app, look in ~/Library/Application Support/iPhone Simulator/5.0/Applications (replace "5.0" with your iOS version, if necessary). You should see a long string of hex digits for each app you've compiled in the simulator; find the one that corresponds to your app, and then look in the Library/Caches/[your app's identifier] subfolder for a file named Cache.db.
This may be the place where UIWebView stores its cache data. If it isn't, game over and the answer to your question is "no, that's not possible". If it is where UIWebView caches data, then it may be possible to populate this Cache.db file in the simulator, grab the file, store it in your app bundle, and then write the cache to the appropriate location when it's time to pre-populate the cache.
At any rate, that's the line of attack I'd use to determine whether it's possible – I'm pretty confident the answer is going to be "no, not possible" unless it turns out the UIWebView cache does reside in your app's sandbox, is writable by you, and you can fool UIWebView by replacing its cache file.
What I mean by force loading is this: if a web page is visited, elements are cached for a faster load the next time. What I mean by force-loading or warming up the cache is to actually issue requests to the uiwebview in the background to load the data into the cache for faster loading so when the user actually clicks on it, it has the information in the cache.
If you use chrome, it's similar to their strategy they use to make surfing a little faster: when a page loads, they immediately find all links on the page and resolve the links so if a user clicks on the link, they don't have to wait for a response from the DNS servers before seeing the page as it's already done for them!
I hope this made a little more sense.
QUOTE:
this is a pretty cool question. consider looking at only what is provided in the developer reference as apple will reject your app otherwise. you can consider 'force-loading' whatever you want in a hidden view to warm up the cache. in this way, you have the ability to add elements to the cache but you don't have the power to remove items from the cache unless you know the internal caching algorithms... I'd say this is less of a hack and more of a technique! – vinnybad Nov 23 at 17:26
#vinnybad: I'm not entirely sure what you mean by "force-loading". Can you elaborate on that? (Sounds like it might be worth putting in an answer rather than a comment!) – Trott Nov 23 at 17:40
I mentioned Amazon CDN and iOS devices because I am not sure which part is the culprit.
I host jpg and PDF files in Amazon CDN.
I have an iOS application that download a large number of jpg and PDF files in a queue. I have tried using dataWithContentOfURL and ASIHttpRequest, but I get the same result. ASIHttpRequest at least gives a callback to indicate that there is problem with the download, so I can force it to retry.
But this happens very often. Out of 100 files, usually 1-5 files have to be redownloaded. If I check the file size, it is smaller than the original file size and can't be opened.
The corrupted files are usually different everytime.
I've tried this on different ISP and network. It's the same.
Is there a configuration that I missed out in Amazon CDN, or is there something else I missed out in iOS doWnload? Is it not recommended to queue large number of files for download?
I wouldn't download more than 3 or 4 items at once on an iPhone. Regardless of implementation limitations (ASIHTTPRequest is decent anyway) or the potential for disk thrashing, you have to code for the 3G use case unless your app is explicitly marked (as in, with an Info.plist setting) that it requires Wi-Fi.
A solution exists within ASIHTTPRequest itself to make these operations sequential rather than concurrent. Add your ASIHTTPRequest objects to an ASINetworkQueue (the one returned by [ASINetworkQueue queue] will do fine). They will be executed one after the other.
Note that if you encounter any errors, all the requests on the queue will by default be cancelled unless you set the queue's shouldCancelAllRequestsOnFailure to NO.
EDIT: I just noticed you already mentioned using a download queue. I would therefore suspect it's more of an issue at the other end than on your device. Connections could be dropping for various reasons: keep-alive setting is too short, resources too low on the server so it's timing out, some part of the physical link between the server and the Internet backbone is failing intermittently. To be sure, though, you probably need to test your app on multiple devices to make sure it's consistently failing across all of them to really be able to say that.
You could possibly try reducing the number of concurrent downloads:
ASIHTTPRequest.sharedQueue.maxConcurrentOperationCount = 2;
This changes the default ASIHTTPRequest queue - if you're using your own queue set the value on that instead.
The default is 4, which is above the limit recommended by the HTTP 1.1 RFC when using persistent connections and when all the content is on the same server.