Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm wondering if I should be relying less on my projects' App Delegate to setup my app - or should this sort of code belong to a singleton class part of the model?
For example -let's say, before my user gets to the first view - I need the app to download some data from a server and I need to preform a few checks and create a BaseDataStore type of class to store the stuff the app downloads. All this before my app starts.
Putting all this code in the applicationDidFinishLaunchingWithOptions seems like the right thing to do - as this is what gets called once the app has launched. My question: Is this the right place to put it? Or do I create my own class for this sort of thing?
In short: YES, you need to create your own classes.
To put all code in the AppDelegate and ViewController classes is a popular habit in iOS.
iOS apps tend to have small (auto-generated) model classes, which are then managed from the ViewControllers or the AppDelegate. Which is the fastest way to create a fart-app and the like.
In case you're building anything bigger then a fart-app, I suggest to take a different approach: A manager class could be in change of your model (setting it up, saving, etc). The AppDelegate then calls into the model manager when needed. Also, the application code generally improves when the "application logic" is placed in the model classes. To accomodate model changes (and regenerating the model classes), the auto-generated ManagedObjects should then be extended via categories containing your "application logic".
For simple project loading data from network your process should be :
Create a custom LoadingViewController
Show it from the AppDelegate applicationDidFinishLaunchingWithOptions
Get the data with an entity manager
With a callback (delegate pattern should be nice) launch the first viewcontroller according to your data
The first 2 steps are for showing the app data is loading to the user (if you don't do that you'll have the Default.png showing a long time). If the first ViewController data can be refreshed you can directly load it, show cached data first and launch the refresh.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
So I have a process for a user to take a photo add info and upload to my database. My question is how should I store that data so it is accessible through all my controllers and when they click the upload button it sends the final object to the server to be added to the database. Would I use core data? Or like a struct? I just want to make sure I am doing this correctly.
This is an opinion oriented answer and it is influenced by developer's familiarity/comfort with the various underlying concepts as well. Hence though I dont consider it as an answer here is my opinion.
Should I use core data, so it is accessible through all my controllers?
Absolutely no! U don't need core data, just to create a shared data source which is being used by multiple ViewController's simultaneously. You can obviously create a Singleton data source object and can be accessed by all the VC's.
But then, core data is not just a shared data source isn't it ?
Core data is a Persistent Data Store where as your structs are not.
Assume user takes a pic, and before it gets uploaded quits the app, or you want to provide offline capability to user, where user can take a pic without internet and queue it for upload and whenever internet comes back your app loads it to server, if u use structs and keep data source in memory, if user quits the app all the efforts done by user to will go waste and obviously user will not appreciate it. On the other hand if u use core data you can obviously have it in sqlite file, and then access it whenever u need it even if user quits the app in between :)
Managed Object Context provides performBlock and performBlockAndWait to synchronize the access to core data in multi threaded environment but with a plain array of struct u have to write it on ur own.
Now there is no point in reinventing the wheel isn't it? We all know data types like array are not thread safe :) So is managedObject Context but managedObject context on iOS 5 onwards provides the amazing handy methods like performBlock and performBlockAndWait which eases the life of developer when dealing with shared data source (managedObject) in multi threaded environment.
Managed Object Context provides notifications about the changes happening in real time and works like a charm with NSFetchedResultsController providing a mechanism to constatly monitor and update the data source
I dont think its a big thing, but in order to achieve the same thing with array u'll have to use KVO. But because KVO wont work with swift objects u'll have to override didSet method and manually throw notification to all VC's when data source changes. Not so elegant solution isn't it :)
Scalability and robustness :
Finally, how many records are u dealing with also matters. I have been a part of a company which uploads and restores thousands of images on/from users device. In a scenario where you are dealing with 1000s of images maintaining a array is always a pain and memory print costly as well because the entire array will be loaded all the time. On the other hand NSFetchedResultsController works on page fault mechanism. It loads data efficiently only when needed.
Scalability is just a matter of adding new fields to managed object entity and robustness is directly proportional to you skill set dealing with core data I believe.
Pinch of Advice :
No matter whether u use array of structs or Core Data, always store images in local file system and keep the local path relative reference in your data source. Holding an entire an image in memory is a real bad idea :D
Hope it helps.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am working on an application that is dependent on data that should be loaded from our remote servers on the application first launch. Currently I simply fetch data using few different functions and then loading the data into different object arrays. I did some research about preloading data but everything I found has specifically to do with preloading data using CoreData objects. Here are my questions:
Should I load data using CoreData objects? Is it OK to load data into arrays of custom objects?
What are the pros and cons of loading that data into arrays of custom objects?
What are the pros and cons of loading the data into CoreData objects?
How should I get the application to load the data, make sure each function has completed and the data has been loaded before the application moves on with loading the primary view?
Thank you!
Both variants of loading data to CoreData objects and into array of custom objects are ok, but mainly serves different purposes. Storing data using CoreData objects is the most common way of storing persistent data. Thus if you might have to support offline mode work of your application in future, that's the right choice. If you know for sure that your application should work only in case Internet access is available, there is no need to support data persistence and storing data into array of custom objects is absolutely enough.
Talking about data server requests chaining. You can perform synchronous calls in application:didFinishLaunchingWithOptions: method. In such case application will display launch screen while data is loading. But that's probably not the best solution because user might be confused what is happening so long period of time before application actually starts. If I were you I would rather create loading screen with some kind of progress bar that shows user that data is loading and how much data is already loaded. For chaining requests in such controller I would use ReactiveCocoa. You can find an example of how to do so by this link.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am working on an iOS application on which the Core Data was already implemented. So I couldn't understand the Core Data implementations from the scratch. But I could work on Core Data while adding new features. But I am having many doubts on Core Data. I couldn't find out a clear idea from any of the blog.
1) Question 1 - I have setup the architecture for application in a way that it has a Webservice controller class, Webservice helper class, DatabaseManager class, UiViewController classes and Model Objects as part of Core Data.
Web service controller makes the connection to service with NSURLConnection and other related functionalities. Once the response got from web service, it gives a callback to Webservice helper class with blocks.
Web service handler class helps to call the services from all the UIViewControllers. Web service helper class acts as an intermediate class to make web services between UIViewControllers and Web service controller. So when the web service helper gets the callback from web service controller, it sends the response back to UIViewController with the help of blocks.
My question is here, What should be flow of storing the web service response in to core data as well as updating the data in the UI. I would like to know the best practice for doing it. Should I save the data in to core data, then retrieve and display in the UI? But saving the data will take time if the data is big. Should core data operation and updating the UI synchronously.
2) Question 2 - I read about Core data operation concurrency in many blogs, still I am not pretty much clear about the concurrency in Core Data.
According to my knowledge, inorder to achieve concurrency, we have to create two managedobjectcontext, one with NSMainQueueConcurrencyType and other NSPrivateQueueConcurrency. Then all the save and update operations has to be executed in privateMOC[NSPrivateQueueConcurrencyType] and read can be executed with mainMOC[NSMainQueueConcurrencyType]. How this operation is related with performBlock?
3) Question 3 - As we can create multiple moc, should that be of NSConfinementConcurrencyType and execute performBlock on all doc for concurrency?
4) Question 4 - What is difference of implementing concurrency as mentioned in Question 2 & Question 3?
5) Question 5 - Consider, I am reading a record using core data and due to concurrency the same record has to update a value. How this situation can be handled. What I know here is that I have to use the merge policy. But I am not sure how to implement this, since I am not clear about the above cases.
6) Question 6 - In an application, how many managedobjectcontext can be created of type NSMainQueueConcurrencyType, NSConfinementConcurrencyType and NSPrivateQueueCOncurrencyType?
Can anyone answer the above questions?
Thanks in advance.
This really should be several separate questions. I will attempt to answer the architecture question, and perhaps touch on some of the others.
The return path from the web service should not reach any view controllers directly. The point where your service helper has parsed the response and validated it is where you want to save to core data. This task should be handed off to another class.
From the view controller side, you want to use NSFetchedResultsControllers (FRCs) to know when the model has changed. You can setup an FRC to watch any number of objects, including a single object.
FRCs were intended for table views, and there are numerous examples available on how to use them for that purpose. If you have a view where you are editing a single object and you use the web service to save updates, for example, you can have an FRC that is watching the edited object. When the save is complete, the FRC will trigger and you can update the UI to indicate success, or whatever.
Core Data
Core Data concurrency is not trivial, as you've discovered. I've had the best experience with the following setup:
A read-only context with NSMainQueueConcurrencyType. This is the initial context that is tied to the persistent store. This context remains for the entire session.
An NSOperationQueue with a concurrency of 1. Operations on this queue clone the main (read-only) context with a concurrency type of NSConfinementConcurrencyType, and are connected to the same store. Only these cloned contexts are allowed to save. These contexts are discarded when the operation is complete.
A merge handler that will merge changes into the main context.
Operations execute on background threads, and are synchronous with respect to each other. This makes merges simple. Cloned contexts are setup with a merge policy of NSMergeByPropertyObjectTrumpMergePolicy, and the main context with NSMergeByPropertyStoreTrumpMergePolicy.
View controllers, and other main-thread activities, use the main context, which always exists.
There are lots of other setups, including multiple, writeable siblings, parent-child relationships, etc. I recommend picking something simple, because you don't want to be fighting Core Data and threading issues at the same time.
I recommend watching this video by Paul Goracke. The inspiration for my preferred stack was taken directly from Paul's presentation.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I want to ask a simple question as i am new in Objective c.
Is there are any difference to write method on AppDelegate instead of UIViewController??
Or which type of method i should write on AppDelegate.
And what if i write method in UIViewController and call from AppDelegate.
Is there are safe to write method on UIViewConroller class and call it from AppDelegate.m file by that UIViewController's object.???
If i write it on ViewController and call it from AppDelegate.m then is it safe or not???
The AppDelegate is shared singleton class.
That means appdelegate object will be created only once in your entire app life cycle.
Creating method in AppDelegate is recommended when you have to process something multiple times in your application and that method may be called through viewcontroller, from appdelegate itself or other singleton class.
Like. Process zip archive, Check version of iOS device
And yes Most important thing
This can also be done in other ways.
However if you want to call viewcontroller method from AppDelegate you need to create an object of viewcontroller or get viewcontroller object from memory. And there should be some solid reason to do that.
It depends on your app Architecture and Requirement.
Hi #Dhaval you can write and call method from any where in your project but for that you have to define the function definition in .h file and that make this function global for the project.
Next thing is that when you define any function in app delegate it access by it share instance because app delegate instance live still your application is not terminate.
This question already has answers here:
iOS Make sure documents are open before accessing
(2 answers)
Closed 8 years ago.
My app depends on the UIManagedDocuments being open. Therefore I basically don't want the user to do anything unless the documents are open. The problem is that opening closed documents is asynchronous. What is the best way to go about this to make sure the user does not enter data to be saved before the UIManagedDocuments are open? I can think of two possible solutions:
1) Should I just wrap every call accessing the UIManagedDocuments in a check to see if it is open and run the code on the completion handler of opening a closed document? This way doesn't seem ideal because the user may do something and expect the results to be saved but it won't be saved yet.
2) The other approach I thought of is to stall the app somehow to wait for documents to open. But I read somewhere that it is bad to block the main thread to wait for the document to open. Can I somehow make the main thread do the opening itself? Or is that bad too?
Another question I have is, if I open all the documents upon loading my app (initial launch), will they stay open until the app is terminated? Or can the documents close at any time for undetermined reasons?
In short, you need to redesign your UI and/or stop using UIManagedDocument. Your Application Launch should be designed so that it can wait for the Core Data stack to be initialized. If you are not doing that now you need to redesign the launch of your application.
Further, UIManagedDocument should not be used as your primary Core Data stack. UIManagedDocument should only be used when you are building a document based application. If you build a proper Core Data stack yourself you will eliminate the need for the asynchronous start up.
However you still want to disconnect your app launch from the data display because of migrations, iCloud integration, etc. All of which can take human perceivable amounts of time and you don't want them blocking the UI.