Getting the managedObjectContext in a document-based app for preferences controller - swift

I've got an OSX document-based app, written in Swift and would like to submit some data from my preferences window controller into my managedObjectContext.
Because the preferences window doesn't seem to be invoked through the NSPersistentDocument, but direct from the appDelegate, what's the best way to get hold of the managedObjectContext for that controller?
Doing most of this using storyboards and bindings so far.
Am I right in thinking that if I instantiate a core-data stack in the application delegate, that negates the one supplied through the NSPersistentDocument (which would be defeating the purpose of the thing)?

What sort of data is this? Are these some sort of settings that are specific to the current document? I am curious only because there may be different solutions here depending on the particulars of what you want to accomplish.
Edit: Usually preferences should be stored using NSUserDefaults, but assuming you do have a specific need to store this data in your persistent document, you should be able to use NSDocumentController to get a list of your persistent documents:
let documents = NSDocumentController.sharedDocumentController().documents
Or get just the current document. Either way you can get the managed object context from there:
if let document = NSDocumentController.sharedDocumentController().currentDocument as? NSPersistentDocument {
if let context = document.managedObjectContext {
// do whatever is needed with the context
}
}

Related

How to get user input with UITextView in different cells in UITableVIew

so I have a UITableView and within each cell, a UITextView. I want the user to be able to edit each UITextView as many times as they like, then go back to somewhere else in the app, close the app, whatever, and then come back and see the same thing they wrote. I have not been able to figure out how to do it.
Please help. I'm still pretty new to Swift.
This is a design problem. Anyway my suggestion is to add a flag in your data model.
Data model (the data that you are presenting in your table). If you don't have any data model, add one.
Example:
class UserInformation {
name: String
isEditing: Bool = false
}
and then save this in your preferred location either in DB (core data, realm etc) or plist (which i don't recommend)
now during the creation of cell. You could just check if this is in editing mode. And then fill up the text field using the saved data.
EDIT: You can't just magically know/retain a state in an object without persisting.
You want to store textView informations in any case, including terminating application, there are some steps to implement this feature.
At first, you have to pick up a place for storing your information:
Hard disk
Your own server
Other service (firebase ...)
RAM is not useable in this case.
Supposing you like hard disk option, let's select a method for storing:
Create a file (JSON, text file, ...), save your information every time user enter a new one, open it to get information back.
Save it by CoreData / Realm in database way (CoreData is like SQL lite, a lite weight database for mobile application supported by Apple)

UITableViewController and Auto-updating Results

I'm currently developing and iOS app in Swift 2.0 and I'm running into the following issue:
I have a custom query that fetches a list of items that populate a UITableView. When tapping the cell I get the ( values[indexPath.row] ) Object and segue it to another view controller for display as well as the list of items (for other actions like swipe to move to the next one).
My issue comes from a background process that fetches periodically new data and saves it to Realm.
Since Realm keeps all nice and updated, the indexPath.row will fetch a different value (the list of values has changed in the meantime due to the automatic updater) resulting in showing something that is not quite what was tapped.
Both Realm and the updater are working, but this results in a confusing experience for the user.
Am I missing something obvious?
Thanks a lot for the help!
PS: I've looked also at ABFRealmTableViewController, but I'm not displaying the whole data but a filtered (and ordered) subset.
Probably the easiest way of preventing this issue is to observe notifications sent out by Realm whenever a write transaction (i.e. an update) occurs and update your UI accordingly:
// Observe Realm Notifications
let token = realm.addNotificationBlock { notification, realm in
viewController.updateUI()
}
ABFRealmTableViewController supports filters via NSPredicate and sort descriptors as well. So you might want to give it another try.

What is the three20 method of passing objects between view controllers?

I have a basic RSS Reader I made from three20 tutorials using TTLauncherView as a menu to different feeds and TTTableViewController to show the feed list.
However, I am stuck at the point where from the feed list I click to view the feed item details. I use TTTableImageItem to display my feed items and I'm clueless as to how I am to use the URL variable in said TTTableImageItem to pass objects to the view controller showing the feed item.
I did some searching and I am lead to think that this cannot be done except via TTURLRequest, which leaves me even more confused.
Most of my code is adapted from IOSGuys tutorial, which uses a custom data source, data model and parser. I have tried making the data source and data model a singleton but to no avail and I'm unsure if that's even the best way to proceed for something as (presumably) simple as this.
Ideally I intend to pass the entire array of feed items with another argument for the index so that I can make use of UIPageControl to swipe between feeds when I'm at a more in-depth view.
Much help is appreciated! I have been spending too long looming around already!
The usual way of doing this is to have some sort of global singleton Data Manager class that manages the data models through Core Data, In-Memory Stores or other ways. Each model would have some sort of unique identifier. Doing it this way lends itself to a URL only stack needed to recover your navigation history without having to write state out to file in order to restore. You also can bring up any page in the app at any place with only a single URL. Using a URL scheme only then becomes trivial as you can do something like:
yourapp://blogs/jd82kd9
and have the blog view controller's init method contact the Data Manager for the blog with the unique identifier of jd82kd9
In your navigator's mappings, you would have something like this:
[map from:#"yourapp://blogs/(initWithBlogID:)") toViewController:[MyBlogViewController class]];
and then the initWithBlogID method would have the signature:
- (id)initWithBlogID:(NSString *)blogID;
see also Three20 : how to pass a class of objects between 2 views

Question regarding iPhone core data and how to duplicate features for multiple users...that doesn't make sense, just read my question :)

So I am working on a simple iPhone app, that uses core data to manage objects. My code is similar in function to Apple's CoreDataBooks app, found here. There is a blank UITableViewCell, and you have the ability to add objects to this blank list. If you hit the add button, a DetailViewController pops up that manages the attribute of each object. In the coredatabooks example, the app is like a library, and you can add book objects. My question is about how I might go about making it so that multiple users can have their own separate list of these objects. Again, relating back to coredatabooks, you would be able to make different library objects whose attributes are the book objects themselves. So using the convenient and easy to use coredata ui, would it be very hard to set it up so that in the UITableView, there was Library-A and Library-B and then selecting one of the libraries would move me to a screen that has the list of different books unique to that specific library? If you then select a book, you would then be able to view that book's attributes as before. So I guess my question is regarding how to put another RootViewController-esque view in front of the native one. As you may gather from this post I am in the learning stage of iPhone development, so I don't even know if logically this is even feasible or the correct way to do it. Any help/insight on this matter would be greatly appreciated! Thanks for your patience!
Create another UITableViewController (.h, .m, .xib files). And you can put some functionality into that view controller for adding library.
You can set that viewcontroller as startup object from MainWindow=.xib file. OPen that xib file -> expand navigation controller -> click on root view controller.
then in attributes window you can select your new controller as startup. you have to also set startup class from identity window.
Ruchir is correct, you can add another table view and controller. You will have to make some adjustments so that it is loaded and displayed first.
Also, it sounds like you will want to create a new entity in your data model for a Library which should have a to-many relationship with the Book entity.
Library <-->> Book
The new table view controller can use a fetched results controller that fetches Library entities. When the user chooses a row, you can set a property on the books table view controller before you push it on the navigation stack. Then use a predicate on the books fetched results controller to only fetch books in that library.

Where's the best place to put your NSUserDefault save/load code?

Using NSUserDefaults to save/load a few small values... it's pretty straightforward.
But WHERE would I place my SAVE or LOAD code?
I want the defaults to LOAD only if/when a certain view is displayed.
I want the defaults to SAVE, only when that view is exited/unloaded/hidden.
(I created a simple app using the "view-based template" and have my string values on the view, inside of UITextFields.)
How about the viewWillAppear and dealloc/viewDidDisappear methods of that view's UIViewController?
Well, your talking about views so:
viewDidLoad / viewWillLoad
viewDidUnload / dealloc
Seem like good candidates. Also, in your init methods, especially if you want to initialize iVars at that point to something from NSUserDefaults.
You should always put the code itself into its own file pair to manage the user defaults, and this module should be responsible for serialization and deserialization, though objects that are serialized should own that virtuosity themselves. You get only the settings you absolutely need in viewDid Load, so as not to slow down the initialization.
If you have capacious user settings, arrays and dictionaries, multiple session data, don't make the mistake of storing them under a single dictionary and key. Split them up.
If your app requires users log on (I do crypto so most of mine do) then only after logon, verifying password from a minimal load of user settings, should you go on to load the heavier session settings. This is on "user time" anyway.