Any Special Considerations when using multiple UIManagedDocuments in iOS - ios

I've been using a UIManagedDocument inside of a Singleton class. I create, open and perform with etc and everything was going fine until I needed to have two separate Data stores with an identical Schema. I've made sure everything was done in the same way through the same class (simply storing the second Database in a second static variable and using a BOOL to ensure the correct document gets used.
The problem is that while my original document works fine and the second document gets created fine, I can never seem to get the second document to open when I call 'openWithCompletionHandler' and pass in the block I need it to perform.
So my question is: Are there any special considerations I need to take into account when using multiple UIManagedDocuments in the one project?
Thanks in advance.

Yes there are. The big one is to make sure they both have unique NSPersistentStoreUbiquitousContentNameKey values set in the document's persistentStoreOptions.
See Rich Warren's well documented example:
Syncing Multiple Core Data Documents Using iCloud
And also my GitHub repo that makes multiple documents easier to set up and maintain in some cases:
APManagedDocument

Related

iOS Cross Cutting Concerns

I have a Swift application i'm working on that allows a user to save various settings about their profile. Throughout my code, there are times where knowing these settings/preferences are important for the application's business logic. One of them is where the user works (their job, (which is a row in a sqllite database that has an ID as a primary key). The user is allowed to select one (and only one) in the app at any given time. Think of it like a profile - they can work many jobs, but only have one selected.
The following are scenarios where knowing the workplaceid profile is important:
In my sqllite database, retrieving work/shift information based upon the currently selected work ID(so not the ID from the database, but the ID they currently have selected). I'm passing this into my query.
In an NSDate extension function, when I go to determine some things about their starting date, I need to retrieve their currently selected profile, and use that for the calculation.
Within a particular view model when I want to show/hide certain fields.
On an alert view to show something related to their current workplace.
Now I think the quick and dirty way to do this is simply create a wrapper class to your nsuserdefaults in a utility class. Sure, all your info is stored in sqllite, but your currently selected app preferences are in nsuserdefaults since I can change this around (and it will change). This would parallel my other cross-cutting concerns such as logging/error handling, where I could use similar utility classes for all my work.
The fact that I might call this helper/utility class from every single layer of my application seems like a typical red flag you wouldn't do. Whether it's logging, or a user service to get information.
I'm curious to know what other people are doing in scenarios like this. When you need nsuserdefaults from all over your app, is the answer "eh who cares, just make a utility class and call it wherever you need it" ? Or is there a best practice others have followed with well-designed iOS apps? I know AOP is something folks tend to recommend. Does that have a place in iOS?
Thanks so much stackoverflow :)
The user is allowed to select one (and only one) in the app at any given time.
This tells me you want to create a singleton class. Every time you want to change the profile, you hit the singleton class and set it. That class encapsulates all the logic to get/set whatever you need, and the accessor functions. That's what I've been doing in my ObjC code for many years, and it has served me well. It's extremely easy to debug, and the rest of the code needs to know nothing about profile management (unless it's the UI part where you choose a profile).

How to dynamically import static information, including an image, into an ViewController

I was wondering whether it was possible to import static information, in my case an image, title and a short description - per item, in a UIViewControlller dynamically?
I'm (trying to) create an app that, for the current UIViewController I'm working on, shows the cooperating partners from the company in a list view. Each of them is shown as an item, containing an image (logo), the company name below and below that a paragraph of information about the company.
I was thinking of something like importing an XML feed (no experience with),
such as
<object>
<img src="/images/logo1.png">
<title="Lorem ipsum>
<description="lalalalalalalala"
</object>
<object>
<img src="/images/logo2.png">
<title="Lorem second one>
<description="lalalalalalalala"
</object>
Something like this mockup
By simply importing such thing, I don't have to make up the whole page, calculate how long the UIScrollView would have to be and don't have to adjust it every time a partner gets added or removed. And it might be quite more clear than a whole view controller.
You have to divide the task into smaller steps.
Read the data from an XML file using NSXMParser.
Show the data in a UICollectionView.
The XML part is quite easy. There are many tutorials on the Internet that cover this. For example this one:
Parsing XML data with NSXMLParser
Second step can be more complicated depending on what kind of a layout you want to achieve. If it is a standard flow layout, the implementation will be fairly simple. Again, there is dozens of tutorials on setting up a UICollectionView. Example:
Beginning UICollectionView
Alternatively, you can use UITableView to show your data. In this case, the implementation would be simpler than for UICollectionView.
More reading:
Collection View Programming Guide for iOS
Event-Driven XML Programming Guide
Depending on where your XML feed/document is coming from. If you're just manually creating the document, and shipping it along with each version of your app, then all you need to worry about is getting the info from it; take a look at this tutorial, it describes some info-getting libraries. Take a look at UIImage for info on loading an image from a file. If you instead mean that you want to get information from some kind of remote, it seems like you have to accomplish three things:
save a document including this various static info, so that it persists between app launches,
load from that document to display the saved information, and
keep this document up-to-date with some remote server (?) whence the most current version originates, in perhaps XML format.
First of all, let us assume that inside your application proper, you're going to have the data you want stored as some kind of NSObject. Check out this tutorial on how to save documents with your iPhone app. It explains fairly clearly how to take something like an array or dictionary (OBJC object) and store it. In the end, because your app is sandboxed you may not need to worry about the format in which it is stored. Whenever your application launches, and decides that it has current info, all it needs to do is load from that archived object and you're good to go. If you have some confusion about displaying the information in the UIView itself, refer to Apple's documentation.
You'll probably want to have a separate class altogether that handles keeping the data updated. This depends on your server's implementation. For example, your class could query your server for its info, determine with a hash whether it needs to get new data, and if so, pull down new data; use NSXMLParser as linked to above in order to parse the data, then save with the above method.
EDIT: regarding your worry about having to redesign the UIViewController every time you load, look into auto layout. You basically can create a nib file for your controller, tell it how everything will be in relation to everything else, then just assign values (i.e., images and strings) to all the fields and pow, you've got a consistent design.

How to initialize an iOS app with default data?

I'm writing an app that needs to access data from a large file every time a button is pushed. I've been reading up on it and the apple documentation says:
"You can create a separate persistent store that contains the default data and include the store as an application resource. When you want to use it, you must either copy the whole store to a suitable location, or copy the objects from the defaults store to an existing store."
Does this sound like the best way to go?
I've created the database with the table I need and put it under "Supporting Files" in Xcode - is this an application resource? Also I'm not sure what it means by "you must either copy the whole store to a suitable location" - is this not it?
Finally, my main question - how do I access the information in the DB in my .m files? Thanks for bearing with me, still very new to this.
Does this sound like the best way to go?
I believe it depends on what kind of information you want to access and if you need to update this information (add new information, modify it, delete, etc).
If you just want to read the data and do something with it, check out Property Lists and XML. In case the data is structured somewhat like a relational database and it is necessary to modify it, check out Apple's Core Data framework.
Is this an application resource?
Yes, it kind is, don't worry about the nomenclature so much but for more clarification check out Apple's own guide about resources.
Also I'm not sure what it means by "you must either copy the whole store to a suitable location" - is this not it?
You can load the store from multiple locations (folders, different files, etc), this just means that you should pick the best that suits your application.
Note, the files you import to your project are stored in the application's bundle and you can't (as far as I know) modify them. So, if you choose to include a Core Data store file, you need to copy the store from the bundle to a location of your preference (ex: the documents folder).
How do I access the information in the DB in my .m files?
It depends on your pick. As it looks like you're more interested in using Core Data, start by looking at the link I've provided above and searching some tutorials.

iOS avoid using old core data model

I have a project on that uses core data and I had migration implemented for whenever I needed to make a small change to my model. However, in the past week I've had to do a complete overhaul of my model and the way it reacts that I can not migrate any of the data.
With this I was wondering if there was a way to check what version of the model I have in the device and perhaps, through code, delete it and completely create a new one from scratch. This may not be the most preferred way, but if anyone has any better solutions than I am open to suggestions.
Two reasonable options:
Use NSManagedObjectModel's usual versioning mechansim. Bump up the version of your new model. Core Data will automatically check to see whether a given store is compatible with one of the models in the app before it opens the store; if not, it'll give you an error when you try to add it. So if you don't provide the old model in your app, Core Data won't use any old stores. You can respond to the error by deleting the store. You can also check a store before adding it using -isConfiguration:compatibleWithStoreMetadata:. See Initiating the Migration Process for more.
Use a different name for any stores you create using the new model. It's not uncommon for an iOS app to use just one or two stores with specific names. You probably know the name you used for the store in previous versions of your app; switching to a different name gives you an easy way to know whether a store is compatible with the old or the new model.
If you have changed the properties so that some of the old properties don't exist in the new model, try using the respondsToSelctor: method to check if an entity responds to an old selector. If it does, you have the old model.

Basic database (MongoDB) performance question

I'm building a web app for bookmark storage with a directory system.
I've already got these collections set up:
Path(s)
---> Directories (embedded documents)
---> Links (embedded documents)
User(s)
So performance wise, should I:
- add the user id to the created path
- embed the whole Paths collection into the specific user
I want to pick option 2, but yeah, I dunno...
EDIT:
I was also thinking about making the whole interface ajaxified. So, that means I'll load the directories and links from a specific path (from the logged in user) through ajax. That way, it's faster and I don't have to touch the user collection. Maybe that changes things?
Like I've said in the comments, 1 huge collection in the whole database seems kinda strange. Right?
Well the main purpose of the mongoDB is to support redundant data.I will recommend second option is better because In your scenario what I feel that if you embed path collection into the specific user then by using only single query you can get all data about user as well as related to path collection as well.
And if you follow first option then you have to fire two separates queries to get all data which will increase your work somewhat.
As mongodb brings data into the RAM so after getting data from one collection you can store it into cursor and from that cursor data you can fetch data from another collection. So if we see performance wise I dont think it will affect a lot.
RE: the edit. If you are going to store everything in a single doc and use embedded docs, then when you make your queries make sure you just select the data you need, otherwise you will load the whole doc including the embedded docs.

Resources