Where is the proper place to initialize data in a core data store? - iphone

For an iPhone app that has to have a bunch of data inserted before the user can do their thing on first launch, where is the correct place (in the code) to insert that data? I'm looking at between 700 - 800 records total between a few tables.
I initially tried doing it in applicationDidFinishLaunching:. This worked fine for the iPhone 3gs, but caused a consistent first-launch crash on the 3g. After digging into the problem, i found that on the 3g, the app wasn't responding fast enough (presumably because it was busy dumping loads of data into the persistent store), so the OS was killing it under the assumption it was unresponsive.
To fix this problem, I moved the data initialization process out of appdidfinishlaunching and spawned another thread from the first view controller that shows upon launch. This works most of the time, but every once in a while the app crashes with a 134030 error in core data, which according to the apple constants reference, is:
NSPersistentStoreSaveError
Error code to denote that a persistent store returned an error for a save operation. This code pertains to errors such as permissions problems.
This error pops up when calling save: on the managedObjectContext.

Ideally towards the end of development you would populate this data into a Core Data store and add that to your project. On first run, you then copy that store from the app bundle over as the user's Core Data store. This should work for your case.
In the case where this is not possible, one would perform the import on a background thread.

Related

CloudKit automatic background backup

I'm currently working on a project that uses CoreData for data saving in swift, and for the purpose of synchronization I wanted to use iCloud, and the first thing I thought was on the CoreData iCloud implementation, but since it's now marked as deprecated I started using CloudKit, and everything works fine until I try to make a backup of the information after an internet connection is stablished (in case of failure when the information should be updated), the app does not store files, just data, all CKRecords are working fine.
My questions are:
Can you synchronize the information after the application is terminated?
Does CloudKit connect to the automatic iCloud synchronization, the one that happens when the device is plugged and has an internet connection.
The current structure is:
CoreData for local saving and withdrawal of data, and CloudKit for Cloud synchronization.
So far I understand that: CloudKit does not interact directly with CoreData and all actions involving data synchronization must be done with the Api calls.
Thank you for your help and if I forgot something please let me know.
1) When your app is terminated it isn't running so you can't sync anything. You would need to re-launch your app (possibly into the background?), but there are some serious limits to what you can do to have that happen without user intervention. Here's a couple threads that might shed more light: Launch app in background automatically? and Will iOS launch my app into the background if it was force-quit by the user?
2) Out of the box CloudKit doesn't do anything 'automatically', it does what you tell it to do. You will need to set it up to fire at appropriate times in your code (when something changes), and in response to push notification for changes from other devices.

NSUserDefaults Inconsistency or device inconsistency? - iPhone

I have developed a server based app for iPhone. But according to client requirements and to avoid overloading on server side, i am required to store data on local end. It is all text and typically 2-4 MB in size.
For this i'm using NSUserDefaults instead of sqlite or CoreData.
The app has been tested successfully for around 2-3 months during it's development as well as post development testing and never shown any type of inconsistency in data storage, updation or deletion on any sort of iphone device from iphone 3G - iphone 4S.
Now there is an incosistency issue in the live app, when user leave the app idle on a screen for around 15-20 minutes and doesn't press home button means app is not in the background.
In this case, data seems to be lost.
But as soon as refresh app, in that case data appears again & app starts functioning normal again.
Here lies the main problem that when i'm refreshing, i'm doing nothing but only fetching fresh data from the server it can be simply one to five records or nothing at all.
Then app is refreshed, all of the records are shown & it functions normally.
I have been trying to spot the issue for around 3 days, and it's not happening on my device (iPhone 4S). As far as i can think, it seems to be problem with the old devices.
Previously in testing, none of this happened on old or new devices.
My questions are -
a) Is this an incosistency in my coding?
b) Are NSUserDefaults not trustworthy for database management for live apps?
c) Is it a device version specific problem related to NSUserDefaults?
Anybody faced/facing the problem with NSUserDefaults??
Please suggest me something i can do for this or tell me i have to do all the database work again for the next version using sqlite or CoreData.
Anyhow this is critically important and needs to be fixed.
Any help is appreciated in advance.
As my suggestion for you please introduce the Sqlite database integration because of the when the short size of the data store and of cause it's good rather then the Sqlite but it's not working into large number of the data that time must use the Sqlite or coredata.
so i suggest to use the Sqlite data and coredata.

Loaded Data and Multitasking?

I am writing a utility where data for games is written to disk at various stages throughout the game (including, but not relying on when the app exits). My question is currently I am doing my initial load using application:didFinishLaunchingWithOptions: but was curious about what happens when the application goes into the background / is suspended etc. Currently I am assuming that all my loaded data will hang around and I only need to do a load when the application initially loads. Is this the case or can iOS flush my stored data and I should look at checking if a load is needed in say applicationWillEnterForeground:
Also its a pretty small amount of data (20 small NSArray objects) but I guess I could always save and clear the data store when I get applicationDidEnterBackground: and reload on applicationWillEnterForeground: Or given that its just a small about of data would I be better to just leave it resident at all times?
Save your state when you get applicationWillResignActive:
That happens when you go into the background, or get a phone call, or several other interruptions occur. This is a better place than applicationDidEnterBackground: since that doesn't get called in devices running pre iOS 4.0 (which only matters if you support ios < 4).
Once your app goes into the background or is interrupted it can get killed without any warning, so this is your last sure chance to save/flush state data.
There is no need to reload data when you return to the foreground. If that happens, your app is still in memory with its data still there (except possibly view(s) may have been unloaded)
I advice that you always save your in-memory data when your app moves to the background. When in the background iOS may terminate your app when it needs the memory and you won't be notified when that happens.

Iphone mapKit ,Large Images & Large data causing memory warnings & crashes

I am working on an app and now I am stucked. I think I this is due to lack of earlier planning. Actually I earlier didnt know that I will be getting so much of data in my app and thats why now at the final stages of my app , I am getting memory warnings.
Basically I am using a MapKit and getting the data from my server , store them in arrays and use that data to display something on map, thats a huge amount of data which I am getting from server .
In some other view , I am downloading large images from server and again some large data to display on image and using arrays to store that data.
I have checked there are no leaks in the app. But the problem is that when I zoom in and out of the map and go back and forth and then again zoom in and out of the map, I recieve memory warnings, my previous views are unloaded. The problem is that previous views also get their data from server and since my app target users will be 3g users and not WIFI , it will be very difficult if again and again they go back and whole data again gets downloaded from server.
SO basically my problem is that how to store large data? Is there a way to reduce the memory usage of MapKit or is it a known bug? Please help me. its very urgent . I m stucked in it from long and not able to get any solution
You could use ASIHTTPRequest and setup a ASIDownloadCache. This way when a controller is forced to unload the data and has to re-download it, the data is already locally available.

Do NSUserDefaults persist through an Update to an app in the Appstore?

Is this the case? Do NSUserDefaults get reset when you submit an update to an app on the App Store, or are they reset?
My app is crashing when updated but not crashing when downloaded fully - so I'm trying to determine what could possibly be different in the updated session to the freshly downloaded session.
Cheers,
Nick.
They are usually not reset unless the user deletes the app. For basic data, NSUserDefaults is the best way to save data such as preferences, dates, strings etc. If you are looking to save images and files, the file system is a better bet.
I beleive the answer is YES, it will persist. This also fully documented under the Application Directory chapter in the Apple iPhone OS Programming Guide.
Direct answer to the posted question: YES.
Your problem:
Your app gets crashed due to logic issues. Suppose you store an object in defaults and the app checks it's value on launch (or elsewhere). In you update you could change the way it is checked or used, e.g. you expect a value, but the object is nil, or vice versa. This may cause a SIGABRT or EXC_BAD_ACCESS.
If you had CoreData model and you changed something in your model and update, without managing migration, thats probably reason why your app crashes on update...
I have a similar experience. Our app stores a version number in Settings.Bundle/Root.Plist. This gets displayed through the iPhone Settings app. What we find is that on an Install the version number gets loaded from the app bundle - therefore the version number is correct. On an update however the version number doesn't change. This gives the impression the user is running a previous version of the app. We don't have any logic linked to the version number, it's just for display (it could be used by contact centre staff when diagnosing faults).
Our experience is NSUserDefaults doesn't get cleared when a user updates our app, but the Settings display doesn't get updated either.
Be aware of this case, when your app is running in background and you cannot access your stored values in NSUserDefaults:
Eric:
There have been many threads and bugs about this, but it's happening to me again in ios 9. I have an app that launches in the background in response to NSURLSession tasks and content-available pushes. Reproducibly, if I reboot my phone and wait for a background launch of my app to happen, then when I open the app I find that [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] contains all the system values, e.g. AppleITunesStoreItemKinds, etc. but does not contain any of the values I have set. If I force-quit and relaunch the app all of my values come back. Is there any way to avoid it caching the "empty" standardUserDefaults from before the phone is unlocked, or at least to determine when they are messed up and fix them without having to force-quit the app?
Eskimo (eskimo1#apple.com):
The problem here is that NSUserDefaults is ultimately backed by a file in your app’s container and your app’s container is subject to data protection. If you do nothing special then, on iOS 7 and later, your container uses NSFileProtectionCompleteUntilFirstUserAuthentication, a value that’s inherited by the NSUserDefaults backing store, and so you can’t access it prior to first unlock.
IMO the best way around this is to avoid NSUserDefaults for stuff that you rely on in code paths that can execute in the background. Instead store those settings in your own preferences file, one whose data protection you can explicitly manage (in this case that means ‘set to NSFileProtectionNone’).
There are two problems with NSUserDefaults in a data protection context:
Its a fully abstract API: the presence and location of its backing store is not considered part of that API, so you can’t explicitly manage its data protection.
Note On recent versions of OS X NSUserDefaults is managed by a daemon and folks who try to manipulate its backing store directly have run into problems. It’s easy to imagine the same sort of thing coming to iOS at some point.
Even if changing the data protection were possible, NSUserDefaults has no mechanism to classify data based on the context in which you’re using it; it’s an ‘all or nothing’ API. In your case you don’t want to remove protection from all of your user defaults, just those that you need to access in the background before first unlock.
Finally, if any of this data is truly sensitive, you should put it in the keychain. Notably, the keychain does have the ability to set data protection on an item-by-item basis.
Source:
https://webcache.googleusercontent.com/search?q=cache:sR9eZNHpZtwJ:https://forums.developer.apple.com/thread/15685