Changing Core Data when app starts - ios

I am developing an iOS app which downloads xml data that are valid for 4 hours. I want to check validity and, if needed, update this data when my app starts.
I am using this xml parser to load data http://www.theappguruz.com/blog/xml-parsing-using-nsxmlparse-swift
Right now I am calling beginParse() and parsing data in AppDelegate.swift in function didiFinishLaunchingWithOptions. Is this the correct place to perform this background task?
In tutorial which I posted the guy does it in view controller but I want to use this parser to update coredata and I need it to run in background after app launches.
Thanks in advance

The professional way to do this would be have a function (or even a full class), to manage this download/parse data and asynchronously save in your core data, after that, you can inform the view that you have new content to load (or if there was an error or something).
About where to call the function, it depends...
If you should only show to the user the most updated information (like locking the screen whit a "loading..." or something like it), put the call in the first view controller, just because would be simpler to just call an completion handler to unlock and load the data.
But, if you can load the "old" information, just to be faster and refresh when the new content is available, i think that you can call in the appDelegate with no problem.

Related

When to Persist Object Graph

I have an object graph which represents the state of my (first) iOS app. I've implemented NSCoding for each of the objects so I can use a keyed archiver. I have the archiving and dearchiving working fine. But I'm left with a rather basic question: When should I archive things?
Is it safe to only call it when I get an applicationDidEnterBackground message from my app delegate? Or should I pesist things everytime the user does something "significant" in the interface (like dismiss some view where data was entered, etc.)? What are the best practices for this?
I found the answer to my own question in this document:
https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html
Here is the relevant quote:
Important: Always save user data at appropriate checkpoints in your app. Although you can use app state transitions to force objects to write unsaved changes to disk, never wait for an app state transition to save data. For example, a view controller that manages user data should save its data when it is dismissed.

App structure iOS and Realm: create database when app is installed

I am very new to iOS. I am developing an app with data persistence. I have decided to use Realm for that purpose.
I must to create the database and load data the first time that app runs. I get data from a Web Service in JSON format. I will implement some strategy to update this database later, maybe with iOS Silent Push notifications.
I have read and I have worked about Realm, loading data from JSON... to learn about that.
Now, I need to apply this in my project but I don't know how to start. I need some clues about general idea for the app:
How can I organize my app to load data when it is installed? At what point should I create the database and load data?
I have thought to create a global Realm object y AppDelegate and use it as a global variable. Is it a good idea?
Do I need to set a path for my database? Can I user default path?
If you are looking for a place to start, you can check out the example apps of this UI component add-on for Realm: ABFRealmGridController.
The controller is a subclass of UICollectionView and the example app should demonstrate most of the functionality you are curious about. The example uses the controller to display the top news stories from the New York Times. This involves making a request to their API and loading the JSON response data into Realm.
When to load the data is dependent on how you want the app to function. If the data will be the same for each user, you could bundle the Realm file with the app pre-populated with data.
The ABFRealmGridController example loads data when the user clicks the refresh button and performs the JSON handling on a background thread; a general best-practice.
Finally, unless you have multiple Realms or need to store the file in a specific path, it is probably simplest to use the default path.

swift iOS what ways can I cache network calls

The first thing a user has to do when he/she is launching my app is to select a category and a sub-category from two table views. (relational)
I populate the table views by calling my remote API/Server and the output the data.
But is there a way to cache the data so that I don't have to make a API network call every time?
You can serialize the data returned from the API calls and manually save them on the disk Explanation here
Also you can use core data this is a bit more troubling in the beginning but after the initial setup it is pretty easy to use.

Best way to handle a JSON call and use it's information in all views

I have a API serving a JSON with all the information needed to put into my app, and it will serve with texts and all the news needed for all the views in the app.
This information and JSON will never be big enough that i need to make multiple calls or even paginate, but the information might be changed in the future since it's an app for an event, and some minimum stuff will be added to the information like, sponsors logo, and some stuff like that.
I was wondering, what is the best way to handle this? Make an API call on the appdelegate or something, save it local and make one API call per day to "update" this local file?
Also, technically speaking, how do i handle the information for all the views?
Keep reading this local file everytime a view is loaded?
implement a singleton class that holds your data inside proper data structure(s). you need to download the JSON in the root view controller and display an activity indicator to the user. in every view controller you can access the singleton class object asking for the data relative to you controller.
I wouldn't put it in the app delegate -- the app delegate should remain small and only deal with APP specific issues and to do
generally you want to keep the Separation of Concerns (dijkstra ;))
I would have a singleton MyDataManager that exposes dataWithCompletion: and in that method, decide if you return the cached data (saved locally) or make an HTTP Request to update it)
For starters you can make a shared instance (singleton) to handle your API calls with AFNetworking or what ever you prefer.
Doing this only once a day is not a bright idea if the response is very small, eg. 5000 characters is only 5kb. You can download and save the images once. So I would prefer calling your API every time the app launches in didFinishLaunchingWithOptions.
To handle the views from your response, you need to make sure your JSON response structure (keys) are always the same.
Example: self.eventTitle = [response objectForKey:#"event-title"]; where "event-title" should never change, your app will crash or give a (null) value.
You can create a singleton object with the json serialize method. The you can instantiate your method to serialialize a JSON that is inside your singleton object wherever you want.
You can follow this guide: http://www.galloway.me.uk/tutorials/singleton-classes/

ios App improve network performance by requesting data up front

I have an application that I'm writing that pulls data from a few network sources:
1) list of blog posts (UITableViewController)
2) list of videos (UIViewController with an embedded UIScrollView)
3) list of images (UIViewController with an embedded UIScrollView)
Right now, there is a home screen with a menu and when you push one of the buttons, a destinationViewController (described above) is what loads the data on demand. I've noticed this is quite slow, especially when on a cellular data connection as opposed to wifi.
I was thinking about creating a class that requests all the data up front and kick it off every time the app is reentered. Does anyone have suggestions that could help me answer the following?
1) are there any classes, frameworks, or existing i code i can use to kick off these requests in a single place?
2) how do my destination view controllers (mentioned above) get the data?
3) how do my destination view controllers get informed that the data is ready if they happen to be invoked before the data is available?
4) is there a better strategy i should employ?
I appreciate the help.
Thanks,
jas
Off the top of my head, I would make the request class you mentioned and start all the request methods in applicationDidFinishLaunching in AppDelegate. I would also probably make custom NSObjects for each type of object you would be fetching and in each of your request class methods, convert the fetched data into said object, then cache each object to disk as they are downloaded. Then in your viewcontrollers, fetch the cached objects as needed.
When you are cacheing, make sure you cache each object with a key that will 100% be unique, because you are going to want to run a check on the current local cache before you start a new download. I would probably string together the file type and file name, and set that string as the key for the cached object.
To run the check on current cache in your request class methods, something that says "if current cache contains object for key:
uniqueKey... do nothing. If else, start the download and cache the object when finished."
Also run a check in your view controllers, because you're also going to want to handle the case where your view controller is requesting a cached object, but it hasn't downloaded yet. So something along the lines of "if current cache has object for key:key, great! use it. If else, start the download... cache it... then give me a call back here so i can use it while I display a loading message to the end user."
Im sure there are other scenarios that you are going to have to deal with, but that's the theoretical direction I would head in.
EDIT:
check out this, it will probably help you a lot. I think it also uses Ego Cache (if you dont want to write your own cache methods): https://github.com/Infusion-apps/Download-Manager
EDIT 2:
I also agree with #RyanDignards point #4. If possible, avoid fetching data you don't need. However, only you really know your UI/UX and app functionality, and my suggestion is assuming there is a good chance your end user is going to be using your app for the sole purpose of consuming the content you provide. So they are most likely going to be wanting to read the blog posts, watch the videos etc... The call is up to you, if you think there is more of a chance that the user will be viewing all the content than not, I would go the preload route, because nothing pisses off a user like having to wait.
1) RestKit is generally regarded as one of the the standard web interaction frameworks http://restkit.org
2) RestKit provides methods such as -[getObjectsAtPath: parameters: success: failure:] or post, which will provide the response in success. Additionally, it can convert the response directly into the respective objects for you with mapping.
3) Generally I would post a notification which is unique to that request, and any controller interested would get notified, with the response located on notification.object within the listener. Additionally most network requests provide for a callback handler where you could update the UI directly.
4) I would advise against preemptive loading since you're using resources for something that you may not actually use. My advice would be to breakdown your calls to the smallest possible level, then as the notifications are posted, that data would be inserted into the UI.

Resources