SKMapsVersioningDelegate Manage update with local maps.json file - ios

I'm writing an app that use skmaps , after this question/answer :
skobbler can i cache json data?
i have passed to a local maps.json file, instead a direct download each time the app starts. Now i'm trying to manage the update process of the map with SKMapsVersioningDelegate.
-My first question is, what does it mean update maps? This delegation methods in a standard implementation will simply overwrite a maps.json file with a new version if it become available during the use of the app or the delegation will'not update the json file in my app and it update only the packages of the map that i have already downloaded for offline use?
-If the delegation works on or replace the maps.json file , there's a way to simulate a map update? In my resource folder i have a json map file with a version set to 20140910. Anyway if i log my actual version :
SKVersionInformation *latestVersion = availableVersions[0];
NSLog(#"Actual version %#",latestVersion.version);
i retrive this version number 20141230. During this process SKMapsVersioningDelegate is never been called. SKVersionInformation where search information?

Please check the 2.5 map update demo.
It should not matter if the Maps.json file is stored locally or remote, it's the version file that decides if new maps are available.
The update SDK will detect that a new version file is available and will update it. Once this is done you will have to manually decide, for each onboard map package, if you want to redownload it or not.
The update API will not automatically update the local Maps.json, so you'll have to do this manually. This being said, for updating the onboard packages you don't need to reparse the Maps.json file but you only need to know their name (identifier) - i.e. for the state of California this would be: USCA. The package identifiers don't change from version to version

Related

In Unity3D for iOS when loading on demand resources, how can I check the latest version is already loaded and if not, what is the download size?

I've recently transitioned my iOS Unity app to use asset bundles as on demand resources. This all works great! The only problem is that when the application first starts up and all the ODRs are preloaded it just starts to download them from the apple servers. I need to know before preloading them if they require downloading and if so, how big of a download. I need this info to show a prompt for the user to let them know that additional data needs to be downloaded and maybe turn on their wifi etc.
If you are using WWW class then there is this WWW.LoadFromCacheOrDownload, this function takes in a version parameter which you can probably use for checking on versions.
If you are using UnityWebRequest, then maybe you can use the meta files which get generated with asset bundle and then download it and read version or a hash (You will probably have to google a little bit on this what to use) to actually look if you have a version change and do you need to download new version or not.
If none of the above suits you then the hard coded way would be to setup a list of your asset bundles with your versions on a webserver and download it to match it with your local version everytime you start the app.
I hope this atleast helps you look in the correct direction.
I've managed to do this myself in the end. My current setup is the following:
I have a bunch of assetbundles marked as On Demand Resources.
When I build the assetbundles I save a file containing the CRC and file sizes of all these bundles and I save it in StreamingAssets to always have it available
Whenever the app starts up, I try to load the assetbundles from PersistentDataPath against their latest CRC (at first launch there will be no bundles there)
If any bundles are missing or have invalid CRC, show a prompt to the user that x MB of data needs to be downloaded (taken from the file made at build time)
After the ODR resources are downloaded, I reencrypt the assetbundle from res:// (the only way I could access it) and move it to PersistentDataPath
Whenever a new updated comes it, it should contain new CRCs for the changed bundles and the process should restart
It seems to work quite well. The only real issues that I have is that I currently don't know how to delete the downloaded ODR data, and there could be a version mismatch if a user installs the app and defers downloading the extra data, and only opts to do so when an updated version of the app (with different bundle CRCs) is available on the server but they still stay on the older version. This would probabily load the new bundles but will fail the CRC checks for them...

Enhance Resilience of Local Storage in Hybrid App

I have developed a hybrid mobile app that has been running on IOS, Android and Chrome reasonably well for over 5 years. My app uses an indexedDB database to maintain the state of the app and save it between restarts, however there are some cases where IOS can clear the indexedDB particularly if the client device is running low on memory.
I would like some help on how to maintain a parallel copy of the indexedDB using the native SQL database on the IOS device, in order to increase the resilience of my app, based on the hopeful expectation that IOS will not arbitrarily decide to clear an internal SQL database belonging to the app.
I understand how to communicate in both directions between Objective C and Javascript but I have not the foggiest idea in Objective C how to:
Create a SQL database in the app file system
Choose where to place the SQL database in the app file system
How to write a new key value pair to the database
Overwrite an existing key value pair in the database
Read back all key value pairs from the database (I expect there could be up to 1000 of these in practice) and pass these efficiently back to the javascript code.
Clear the database and start again.
Any pointers to useful resources on how to achieve this or better still coded examples would be most appreciated.
I would just like to add that I am not using Cordova or any other similar app development environment, so please do not suggest a SQLite plugin that is part of a bigger environment. I have got to where I am with a bespoke coding approach and I would like to keep it that way.
I have explored the idea of paralleling up each indexedDB save with a write to a file in the IOS App Documents Folder with the hope that this is less likely to be wiped than the Caches Folder.
Following each indexedDB setItem with a key-value-pair I pass a request to the objective-C IOS app code to create a text file in a sub folder created with the App Documents Folder, with the name 'key'.txt and the contents set to value.
Following each indexedDB removeItem, I pass a request to the objective-C IOS app code to delete the corresponding text file 'key'.txt.
Following each indexedDB clearAll, I delete the entire sub folder created above.
Now when the app starts up and discovers an empty localForage database, I pass a request to the objective-C IOS app code to test if the sub-folder with key-items is there or not.
If it is not, then this is a fresh install of the app and continue as normal for such a case.
if it is, then this is a case of the indexedDB database having been deleted.
In such case, I request the objective-C IOS app code to return the set of keys, by examining the contents of the folder created above and stripping off the .txt bit and in the case of the IOS Simulator ignoring the DS_Store file.
One by one I then request the contents of each key file and load them back into the previously empty localForage database and when this has been done I can continue as if it had not been deleted.
I found that it is necessary to use a zero duration timeout in the javascript before requesting each value to prevent call stack exceeded errors when restoring large databases.
This approach seems to work and I can test this any time by using the Safari Developer Resources tab actions to clear the database and then manually restarting the app. Using the same tab you can watch the indexedDB database being repopulated.
Due to the size of my database, I actually created a set of sub folders of different types of key, so that I could choose the order in which the database items were restored, especially as my app is often brought back to life in the background following a significant location change and in such cases there is an imposed maximum time limit on how long the app is given to do such a recovery. This refinement is of course optional and only needed for large databases.
The following notes are for anyone who wants to try this approach and assumes using Objective C in XCode 10.1
Use NSHomeDirectory() and stringByAppendingPathComponent #"Documents" to get the Documents folder.
Use stringByAppendingPathComponent to create a sub folder path for the keys sub folder.
Use fileExistsAtPath to check whether the keys sub folder exists already
Use createDirectoryAtPath if it does not.
When saving or changing items in indexedDB use the stringByAppendingPathComponent to create the key file name path e.g. Base.txt for a key of 'Base'.
Use fileHandleforWritingAtPath to get the fileHandle for a file
if fileHandle does not exist then need to create it using writeToFile to create the 'key' file
if fileHandle does exist then truncateFileAtOffseyt:0 (important) to clear it and then use writeData to create a new version of the 'key' file.
In both of the above specify UTF8 encoding.
When removing items from indexedDB do the same to get the key file path and then use removeItemAtPath.
The device can be cleared by removing the entire sub folder using removeItemAtPath.
The restore process uses contentsOfDirectoryAtPath to read the set of keys in the sub folder.
The restore process for each item uses stringWithContentsOfFile to read data files and return the contents enclosed in quotes using a call to stringByEvaluatingJavaScriptFromString
Hope this helps.

Download files with AFNetworking, check for updates (Etag, last modified)

I've been searching around documentations and also the web, but I am still unsure how to do this right:
I have a large number of files that I want to download and store locally to display them in my app (PDFs, images in various resolutions, ...)
I have a number of requirements:
The files need to be available in offline conditions.
The files need to be up to date (check for new versions of the file regularly like twice a day)
I need access to the local file URL, not only a NSData memory representation of the file
the local files should never be deleted automatically, only through user interaction.
I am supporting iOS 6.1+.
I am using AFNetworking (currently 1.1)
I have control of the hosting server, so I can set appropriate http headers.
This is what the process should be like:
Example: UI requires resource
check if resource is available at local path, if yes load resource from local path
check server for new version, HEAD request
compare Etag or modified date with local version
download file if it has been updated
replace local file
notify the UI that a new version can be loaded from the local path
Now my question is, how should I implement this given the requirements?
Specifically, which parts of this can be done by NSURLConnection / AFNetworking, which parts do I have to implement myself?

Automatically update iPhone app database without making user do anything

I have a pretty strong background in C++ and am making the switch to Objective-C to try to make an iPhone app. A main component of my app will be a database.
1) Is there a way to update the database of the app without requiring users to update to a new version from the App Store?
2) If there is, where & how do you pull the data into your app? Do you have to pull it from a website?
2a) Is there a way to make a master copy of the app that I can make data changes in and then have that copy update all other versions of the app?
If my database contains info that is only updated by me, do I need to store each piece of data as an object?
Ex: One "object" may have a name, a type, a number, and a picture
names, and types will overlap but numbers and pictures will be unique
Thanks again.
Yes, copy the datdabase (SQLite) from the application bundle to the documents folder. For an update, download over top the old one. Also, you can use something simpler than a database like an NSDictionary stored in a .plist file.
Yes, from a web server. NSDictionary has methods that let you download directly from a URL (dictionaryWithContentsOfURL). So does NSData.
Why not use third party tools to edit data? You can store a NSDictionary in a .plist file and edit it there, then upload it to the web server.

Replacing Resource files on new BlackBerry app version

I am maintaining an existing BlackBerry application (implemented as a MIDlet). The application contains a number of data files that get bundled with the app as resources. Some of these data files need to be updated for a new version of the app. When the user goes to install a new version of the application (via URL of Jad file), it prompts them with the following message
"Persistent data exists for the application. Would you like to retain this data? "
If the user selects "Yes", it looks like the app continues to use the old resource files.
This is so surprising to me. First of all, am I losing my mind or will an upgrade really not overwrite existing resource files? Is there any way I can force it to?
Thanks,
Jeff
I think that message is only relevant to existing RMS records. Are you positive that your app is still using old resources? That sounds unbelievably strange (even for RIM). Anyway, this should be easy to verify if you change some image resource you're using in one of your screens or something.

Resources