On-demand resources - Force purge/clear of downloaded resource bundles - swift

I have an swift4 app that is having certain issues where on-demand resources packages hang when downloading. The issue appears to be related to different versions of resource bundles being used in testflight environment as opposed to prod. Some users indicate that the packages do not download, but after several days (presumably after the bundles have been purged by the OS), the downloads start working again.
My question is, is there a way to forcibly clear the downloaded bundles rather than waiting for the operating system to remove them at its own leisure. I know it can be done via xcode (via purge in the data panel), but I need a solution that is native to the app itself.
(Using the NSBundleResourceRequest.endAccessingResources() function will only stop the resources being used, but will not remove them)

In short, there is no way to delete ODR programmatically. I asked a similar question on Apple Developer forums and got the answer:
There is currently no way to programmatically purge ODR resources. It is up to discretion the OS.
When a new network request for ODR content is initiated, the system will do a sort of inventory check, checking what is currently in memory and if there’s room for new memory. This check also takes into account several other metrics, such as which assets are currently being used, which were used recently, is the asset being used for the UI, etc.
After this is done, the system will determine how much of the chosen assets are to be purged, so that there is enough room to fit the new content. If I remember correctly, the OS will try and delete whole assetpacks. What this means is, if the system is purging assets, it will purge resources that are grouped together such as, all assets from Level 1, Level 2, and Level 3, provided the user is on Level 4. So, the system might purge slighly more space than exactly needed.
If you would like to change your app's ODR assets, you will have to submit an update to your app.

Related

Updating my Windows Store App [duplicate]

This question already has an answer here:
How to Delete Files and Application Data Container Values in One Go?
(1 answer)
Closed 8 years ago.
I would like to update my Windows Store App, but I need to delete everything in the local state folder of the application:
C:\Users\usr1\AppData\Local\Packages\myApp\LocalState
I am not familiar with the process of updating Windows Store App and the official documentation does not clarify how can I clear the folder just as if the App was reinstalled.
I was wondering if I had to do this by hand (using the version number of the App) or if there was an automated way to perform it.
Let me first give a little background. By design, app data is preserved across the installation of app updates. The reason for this is that the versions of your state (app data) are typically a separate concern from the versions of the app itself. That is, an app could go between versions 1.3 and 4.1 and still use the same app data structures.
The version of the app data is set through Windows.Storage.ApplicationData.SetVersionAsync (http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.setversionasync.aspx). Where this primarily matters is with roaming data, as this version mark determines what distinct copies of the roaming data are preserved in the cloud.
Now in your case you're talking about local app data, not roaming, in which case you can either use SetVersionAsync, or you can simply maintain a version number in an app data setting yourself. For your scenario (which sound like clearing out a cache of sorts), using your own setting is probably better, because if/when you use roaming state you won't be having to change the app data version with every app update.
If you have a version number of your own, then, simply write your updated app to check for whatever version you don't want to carry forward. If that version exists, then call ApplicationData.ClearAsync(ApplicationDataLocality.Local) (see http://msdn.microsoft.com/en-us/library/windows/apps/hh701425.aspx). You can call ClearAsync with no args to clear local, temp, and roaming all together.
If for any reason you have state that can be migrated instead of rebuilt, then you can use that version number to check for what you need to migrate.
The other way to do this is to use a background task with the ServicingComplete trigger. A guide for that is here: http://msdn.microsoft.com/en-us/library/windows/apps/jj651556.aspx. You'd basically just have the background task call ClearAsync as before and/or migrate the state.

Wireless updating in objective-c

I have an application in the store that has a bunch of UITableViews, each has a bunch of items that when selected, load a UIWebView that loads a local HTML file. The reason I do this is so it allows for viewing when there is no internet access, however it makes it tedious to update.
How would I go about both keeping local files, and keeping web files, so that If I update one on the web it would let the user know there is an 'update' and it can download and overwrite the old file with the new. Is this possible? Like I would make myself a backend to edit my HTML, and have a connection to the app so whenever I clicked save the app would know to ask the user to update the files so I don't have to submit to apple for such small updates.
But I still need to allow offline viewing in case they didn't have internet access.
What technologies or techniques would I have to research to accomplish this?
Thanks
what you're looking for is an html5 concept called application cache.. it directly addresses your problem. With app cache you can cache static content at the client side, which they can view even if they're offline, yet they can update it when the content on the server changes. If you look around you'll see people use this for the iPhone as well.
update:
What way would I go about rewriting files on the phone from ones on a server?
you basically update the cache to do that. from the docs:
The application cache automatically updates only if the manifest file
changes. It does not automatically update if resources listed in the
manifest file change. The manifest file is considered unchanged if it
is byte-for-byte the same; therefore, changing the modification date
of a manifest file also does not trigger an update. If this is not
sufficient for your application, you can update the application cache
explicitly using JavaScript.
I encourage you to do some reading on html5 local storage just to get the concept of local cache and manifest files etc, then just follow through the instructions on the apple docs.. It's not that difficult.
You can cache the content as abbood said but that won't allow you to provide initial offline content.
Another approach would be to use NSURLProtocol, which allows you to swizzle a request. For example, if you have a request for "http://google.com", you would be able to either change the URL or load your own content (say from a local directory).

Synchronize Directory of Files Between Server and iOS Application

I am building an internal iOS application (so - it won't ever be in the app store), and I need to keep a directory of content synchronized between a server and each of the instances of the iOS application. This would be easy enough if I just wanted to delete and re-download this content each time, but I would rather use something similar to rsync to only download the elements that have changed.
I haven't found any good way to utilize rsync. I considered looking at Objective-Git as a possibility here, but at a quick glance it looked like there is still a lot of the support for remote repositories that isn't supported yet.
As a final note, while this won't be in the app store, I will not be jailbreaking these devices and I would prefer to not rely on any private API's (although if there was an elegant solution that utilized private API's I might consider it).
Thoughts?
ADDITIONAL NOTE: This needs to be an isolated solution. I won't be relying on outside services (like Dropbox, Box.net, etc...). This needs to work solely between the device and the server (which is on a local network with the device).
Use HTTP to list the contents of each folder on the server.
Compare last modification time of each file with those on the device, and identify added/removed files.
Get added and modified files, remove deleted files.
It sounds like you're maybe asking for a library that already does this, but if you don't find one it's obviously moderately easy to write this from the ground up using stat(2) on the server and the same or a higher-level equivalent on the iOS devices. Have the iPhone send a tree of files with their modification date to the server and get back a list of insert/delete/update operations to do with the url (or whatever) for each one so you can do them incrementally on a background thread. Have the information from the server for new/updated files include the mod date that the server has so you can set it to be the same on the iOS device and send that when asking the server for the status of each file (kind of hack using the file system to store that, but it works).
Why not just set up a RESTful interface and do it across HTTP; that way you could query the modification times easily enough to determine whether client or server files need to be updated. You might also want to keep track of what files on the client have been synced, so you can easily know which files to add or delete. This can be done with a simple .sync file or using a plist / sqlite / etc.
If you'll consider FTP, there are some pretty advanced client libraries available.
For example, the iOS Chilkat bundle includes an FTP client library that supports synchronization in both directions. It's not free, but it's pretty cheap -- and you get a ton of other stuff that will likely prove useful someday. Here's an example of iOS pulling down all additions and changes (mode 2):
http://www.example-code.com/ios/ftp_syncLocalTree.asp
One caveat -- judging solely from the example, it doesn't appear to synchronize deletions. If this is a requirement, you could do it yourself without too much effort immediately following a sync.
acrosync (see https://acrosync.com/library.html) seems like a good fit given the initial question, however I haven't used it myself yet.

Guaranteeing consistency while accessing files on a web server

I'm in the process of building a simple update server for an application. The parts of the application being updated are configuration files; the most up-to-date copies of these files exist on the update server and these files can be edited by the individual managing the application (the "application manager") at any time. However, I don't want the application to be able to download one of these files while the file is being edited by the application manager; this would obviously cause consistency issues. How can I prevent these files from being accessed in an inconsistent state? Alternatively, would a solution be to provide a checksum along with the file that the application could use to determine if the file was received in a consistent state?
EDIT: I've seen this post concerning access restrictions using .htcaccess and think it could be of use. However, I want the application manager to do as little thinking as possible; having them forget to re-allow connections might be problematic. That being said, they're going to have to do some work at some point; maybe this is the way I should go?

Syncing Core Data model between Mac and iPhone

I am currently building my Core Data model, which I would like to sync between the Mac and iPhone versions of my application.
I will be using Bonjour for device discovery, etc but I have a question regarding the data sync part of the problem.
So far I have added a UID and modification timestamp to each object that will be involved in syncing, so I should be able to match up objects and detect which ones have changed.
Are there any good links, resources out there regarding writing sync code for this type of situation, i.e. syncing records between two instances of a model?
Sync is a problem with quite a few edge cases which have been solved many times by people in the past, so I was expecting to find some info on the subject but all I can find are links to Apple's SyncServices (which doesn't exist on iPhone) and some MS sync technology.
I'm really looking for general theory so I can implement it myself, not necessarily a ready-made solution.
The SyncML specification may be of help, but it's quite hard to read and obviously biased towards SyncML.
I've had to implement this for Task Coach, so here are a few ideas:
A modification flag is enough, a timestamp doesn't really provide much more information. Typically, my objects are in one of these states:
None
New
Deleted
Modified
The following transitions happen when the object is modified:
None -> Modified
New -> New
Deleted -> (should not happen)
Modified -> Modified
and the following ones when it is deleted:
None -> Deleted
New -> Actually deleted (it may be removed from storage)
Deleted -> (should not happen)
Modified -> Deleted
When synchronizing, the device first sends to the desktop all objects with a status different than None. The desktop asks the user to resolve conflicts if one of these has a status != None on its side. In any case, the object goes into state None on the device, or is deleted from storage if its state was Deleted.
Then, the desktop sends its own changes to the device. There are no conflicts possible since all objects are in state None on the device. Objects on the desktop go into state None or are deleted from storage as well, and sync is over.
There are two types of possible conflicts, depending on the device/desktop states:
modified/deleted. If the user chooses to trust the device, the desktop object is replaced with the device one; else, the desktop does nothing and keeps the deleted state, so that the object will be removed from the device in phase 2.
deleted/modified: If the device wins, the object is actually deleted from the desktop. Else, the object goes into state New on the desktop so that it is restored on the device in phase 2.
deleted/deleted: Duh. Just remove it from storage.
modified/modified: The user decides which values to keep, maybe on a field by field basis. The state stays to Modified on the desktop so that these choices are propagated back to the device in phase 2.
Some conflicts may be avoided if the Modified state is kept for each field, so that for instance an object with a modified Subject on the device and modified Summary on the desktop will not trigger a conflict.
You may take a look at the code for Task Coach for an example (SVN repository on SourceForge, it has both the desktop app in Python and the iPhone app). Actually, in this case I decided to use a simpler approach; I don't keep track of the state on the desktop. After phase 1 (device to desktop), I just make a full replacement of objects on the device with the ones on the desktop. Thus, there are no conflicts (the device always wins).
Obviously, this only works between two fixed devices; if you want to synchronize with several phones/desktop apps, you have to assign a unique ID to each and keep different states for different devices/apps. This may begin to get hairy.
HTH
Marcus Zarra created a framework called ZSync to simplify synching iPhone/iPad apps to their Mac counterparts. Take a look at it, it may help solve the problem.