Category Archives: iOS

Handoff from  Watch to iOS app

download source

On the Watch side, in a button click responder, we call updateUserActivity method, which is a way to hand off data that the user is currently working on. This method is part of WKInterfaceController.h.

InterfaceController.m

Notice the string key com.rtsao.handoff.

You need to go to your project folder’s Info.plist, add NSUserActivityTypes as an Array, then in that array, add com.rtsao.handoff

handoff-info-1

Then in your Watch Extension folder’s Info.plist, do the same thing.

hand-off-info2

iOS app

AppDelegate.m

Run the program. Also, click the power button on your iphone to lock it.

When your  watch turns on, click on the button to activate the handoff. It calls the updateUserActivity method, which means its ready to pass off the current User’s activities to the paired iOS app.

Now click on the home button of your iphone. You’ll see that your iphone is on the “unlock screen”. You will also see that your app icon appears on the lower left hand side. This means that once the  watch passes off the user’s activity to the iOS app, you can activate the continuation of that user’s activity by sliding this icon up.

handoff-appicon

Once you slide up, your iOS app will appear, and the thread of execution will continue in AppDelegate.m’s continueUserActivity. The continueUserActivity method is part of UIApplication delegate protocol methods.

Look at the parameter userActivity. That contains all of the data you need to start processing the user’s activities. Use the activityType to retrieve the id, and the userInfo to get the data, among other data.

Also notice the restorationHandler block. This block takes an array of UIViewControllers. It then sends each of these UIViewControllers a restoreUserActivityState: message, passing in the resuming activity’s NSUserActivity object.

The window controllers inherit the restoreUserActivityState: method from NSResponder, and each controller object overrides that method to configure its window, using the information in the activity object’s userInfo dictionary.

Hence since we only have 1 main ViewController, let’s pass that in. In is simply self.window.rootViewController.

Then in our ViewController.m, we implement:

You now have the user’s activity in your particular UIViewController and its view hierarchy. Thus, this let’s you take care of processing the data in whatever part of your app.

Core Data #3 – sibling Main/Private MOC on a PSC

CoreData Stack #3 xCode 7.3

ref – http://blog.chadwilken.com/core-data-concurrency/
http://stackoverflow.com/questions/30089401/core-data-should-i-be-fetching-objects-from-the-parent-context-or-does-the-chil
https://github.com/skandragon/CoreDataMultipleContexts

https://medium.com/bpxl-craft/thoughts-on-core-data-stack-configurations-b24b0ea275f3#.vml9s629s

In iOS 5, Apple introduced

  • 1) parent/child contests – settings a context as a child to a parent context is that whenever the child saves, it doesn’t persist its changes to disk. It simply updates it own context via a NSManagedObjectContextDidSaveNotification message. Instead, it pushes its changes up to its parent so that the parent can save it.
  • 2) concurrency queue that is tied to a context. It guarantees that if you execute your code block using that context, it will use execute your code block on its assigned queue

Thus, we can use parent/child contexts and concurrency queue to set up our Core Data Stack.

Say we create a parent context. It will act as the app’s Task Master. Its children will push their changes up so that the task master will and executes them in a background queue.

When creating this Task Master context, we init it with macro NSPrivateQueueConcurrencyType to let it know that the queue is a private one. Because its a private queue, the threads used to run the tasks in this private queue will be executed in the background.

Now, let’s a child context. We we create a temporary MOC who’s parent context is our Task Master.

Notice its parentContext assigned to our Task Master.

This implies that whenever our temporary MOCs finish their tasks, (whether its getting data from the net or reading in loads of data from somewhere or whatever task that takes quite a bit of time) and that we call MOC’s save,
this does 2 things:

1) save sends the NSManagedObjectContextDidSaveNotification message, and thus our Notification center observes. We go to handleMOCDidSaveNotification method where we call a method for the parentContext (task master) to do the save.

2) The background context’s changes are pushed into its parent context (task master).

Here is the handler that handles all name:NSManagedObjectContextDidSaveNotification message triggered by our child temporary MOCs.

where handleMOCDidSaveNotification is:

In handleMOCDidSaveNotification, we ignore other context, we take care of these temporary MOCs only. We RETURN and do nothing iff the temp MOCs are NOT tracked in our NSHashTable directory, or if its the UI context.

If the temp MOCs ARE tracked, that means they are temp MOCs, and we go ahead merge our temp MOCs with the UI MOC. We merge our changes with the UI MOC, because the UI MOC is not a parent context of the temp MOCs. The UI MOC is a separate entity.

When a MOC saves, its changes are pushed into its parent context. These however are not immediately written to disk. We write to the disk, after the background MOC saves, sends the NSManagedObjectContextDidSaveNotification notification, we go into handleMOCDidSaveNotification, and in the method saveMasterContext. saveMasterContext saves our parent private context, thus making it write to disk, and if it takes a long, its ok because its a private background queue.

http://stackoverflow.com/questions/30089401/core-data-should-i-be-fetching-objects-from-the-parent-context-or-does-the-chil

In short,

To clear up the confusion: after creating the child context from a parent context, that child context has the same “state” as the parent. Only if the two contexts do different things (create, modify, delete objects) the content of the two contexts will diverge.

So for your setup, proceed as follows:

create the child context
do the work you want to do (modifying or creating objects from the downloaded data),
save the child context
At this stage, nothing is saved to the persistent store yet. With the child save, the changes are just “pushed up” to the parent context. You can now

save the parent context
to write the new data to the persistent store. Then

update your UI,
best via notifications (e.g. the NSManagedObjectContextDidSaveNotification).

Is a GCD dispatch queue enough to confine a Core Data context to a single thread

http://stackoverflow.com/questions/7718801/is-a-gcd-dispatch-queue-enough-to-confine-a-core-data-context-to-a-single-thread?lq=1

Concern
One big advantage of GCD dispatch queues is that it manages and makes use of multiple threads to process its FIFO tasks as needed. Each task gets executed by one thread. However, the it “may” be a different thread that processes the next task.

So – if I understand this right – tasks I hand off to one and the same dispatch queue, could end up running in different threads, potentially handing off a core data context from one thread to another, and having things go wrong. Is that right?

Answer
The accepted answer to that question, using GCD queues, does ensure that a new context is created on each thread, but does not point out the necessity of doing this.

The big thing you need to remember is that you must avoid modifying the managed object context from two different threads at the same time.

That could put the context into an inconsistent state, and nothing good can come of that. So, the kind of dispatch queue that you use is important: a concurrent dispatch queue would allow multiple tasks to proceed simultaneously, and if they both use the same context you’ll be in trouble.

If you use a serial dispatch queue, on the other hand, two or more tasks might execute on different threads, but the tasks will be executed in order, and only one task will run at a time. This is very similar to running all the tasks on the same thread, at least as far as maintaining the context’s consistency goes.

See this question and answer for a much more detailed explanation.

This is how Core Data has always worked. The Concurrency with Core Data section of the Core Data Programming Guide gives advice on how to proceed if you do decide to use a single context in multiple threads. It talks mainly about the need to be very careful to lock the context any time you access it. The point of all that locking, though, is to ensure that two or more threads don’t try to use the context simultaneously.

Using a serialized dispatch queue achieves the same goal: because only one task in the queue executes at a time, there’s no chance that two or more tasks will try to use the context at the same time.

Core Data Stack #2 – multiple contexts and resolving conflicts

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/ChangeManagement.html
http://stackoverflow.com/questions/4800889/what-does-apple-mean-when-they-say-that-a-nsmanagedobjectcontext-is-owned-by-the

Multiple Contexts manipulating the Database

source download

Let’s see what happens when we have 2 contexts making changes to the database. First let’s add in an extra NSManagedObjectContext called privateQueueContext2. Implement the custom set method and create our context to execute tasks on a queue.

Then synthesize it and create the custom set method.

CoreDataStack.m

How we want to test it

We’re going to test what happens when 2 contexts edit a database by having the first context get the first Person and change its name to “Ricky”, then save the context. Then we’re gunna have the second context get the first Person and change its name to “Shirley”. The change, and its related saves will be overlapped.

But first, let’s implement the code where the contexts edit a common object (0-th indexed object of the fetched result array), then do a context save.

We do this for private context queue 1:
1) We have changeFirstPersonPrivateQueue method which responds to a button that changes the 0th Person object’s name attribute to Ricky.
2) Then we have privateQueueContextOneSave method which responds to a button that wants context 1 to save.

I want to emphasize that

We do this for private context queue 2:
1) We have changeFirstPersonPrivateQueue2 method which responds to a button that changes the 0th Person object’s name attribute to Shirley.
2) Then we have privateQueueContextTwoSave method which responds to a button that does context 2 save.

Now that the implementation is ready hook up these methods to buttons.

Specifically what we’re trying to do is

to have context 1 be able to make a change to the first Object, then save it.
to have context 2 be able to make a change to the first Object, then save it.

Hence we should have 4 buttons.

2contexts-view

Now, we know if one context makes “changes and save immediately”, then it gets reflected in the database. The next context that either reads or make further changes will see the updates. However, what if the 2 contexts’s changes and saves overlap each other?

Let’s look at this example:

  • First, click on the “add bulk” button to add Person objects into Core Data.
  • Then, click on the “Display All” button to show all the first/last name of the Person objects.
  • Then, we use context 1 to change the 1st Person object’s first name to “Ricky”. Click the “Context1, make change to Ricky” button to edit Object 1’s name to “Ricky”.
  • Then, we use context 2 to change the 1st Person object’s first name to “Shirley”. Click the “Context2, make change to Shirley” button to edit Object 1’s name to “Shirley”.
  • Then click on “Context 2 save”
  • Then click on “Context 1 save”
  • In this case, you’ll get an error:


    2015-10-27 00:29:56.801 CoreData2[48750:5178513] Unresolved error Error Domain=NSCocoaErrorDomain Code=133020 “(null)” UserInfo={conflictList=(
    “NSMergeConflict (0x7f96bbc0f100) for NSManagedObject (0x7f96bbd0aa90) with objectID ‘0xd000000000040000 ‘ with oldVersion = 1 and newVersion = 2 and old object snapshot = {\n firstName = \”remark: 1445930979.058863\”;\n lastName = \”1445930979.058863\”;\n} and new cached row = {\n firstName = SHIRLEY;\n lastName = \”1445930979.058863\”;\n}”
    )}, {
    conflictList = (
    “NSMergeConflict (0x7f96bbc0f100) for NSManagedObject (0x7f96bbd0aa90) with objectID ‘0xd000000000040000 ‘ with oldVersion = 1 and newVersion = 2 and old object snapshot = {\n firstName = \”remark: 1445930979.058863\”;\n lastName = \”1445930979.058863\”;\n} and new cached row = {\n firstName = SHIRLEY;\n lastName = \”1445930979.058863\”;\n}”
    );
    }

    ..and you’ll come to the abort method:

    ref – https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/ChangeManagement.html

    If your application contains more than one managed object context and you allow objects to be modified in more than one context, you need to be able to reconcile the changes. This is a fairly common situation when an application is importing data from a network and the user can also edit that data.

    Ultimately there can be only one truth, and differences between these views must be detected and reconciled when data is saved. When one of the managed object contexts is saved, its changes are pushed through the persistent store coordinator to the persistent store. When the second managed object context is saved, conflicts are detected using a mechanism called optimistic locking. How the conflicts are resolved depends on how you have configured the context.

    When Core Data fetches an object from a persistent store, it takes a snapshot of its state. A snapshot is a dictionary of an object’s persistent properties—typically all its attributes and the global IDs of any objects to which it has a to-one relationship. Snapshots participate in optimistic locking. When the framework saves, it compares the values in each edited object’s snapshot with the then-current corresponding values in the persistent store.

    • If the values are the same, then the store has not been changed since the object was fetched, so the save proceeds normally. As part of the save operation, the snapshots’ values are updated to match the saved data.
    • If the values differ, then the store has been changed since the object was fetched or last saved; this represents an optimistic locking failure. The conflict must be resolved.

    Say in our example, when our contexts gets the first object in our Core Data, it does so using

    as you can see in the code. Basically, the NSArray you get back is a snapshot of its state. Within the NSArray, we get the 0-th index object, and change its attribute. What we’re changing here is just a snapshot. Now, when you decide to save after you change the attribute in the situation of the 2nd context changing the name to Shirley, it compares the values in its object’s snapshot with the then-current corresponding values in the persistent store.

    Context 2 – no conflict

    In our case for context 2, before it saves, it sees that the current corresponding value in the persistent store is the same as the values in the snapshot it received. In both cases, it is the default value “remark: whatever today’s date is”. Since they are the same, then the store has not been changed by other context(s) since context 2 fetched it, and thus the save proceeds normally.

    Context 1 – conflict

    It does not work for context 1 because when context 1 fetches the object, its snapshot is “remark: whatever today’s date is”.

    However, because context 2 previously managed to change the 0th Person object’s name attribute to “Shirley” and then save. This means the current corresponding values in the persistent store is Shirley.

    This means the values differ, and thus, for context 1, the store has been changed since the object was fetched or last saved. This represents an optimistic locking failure. And the conflict must be resolved.

    Resolving conflicts by synchronizing changes between our contexts

    If you use more than one managed object context in an application, Core Data does not automatically notify one context of changes made to objects in another. In general, this is because a context is intended to be a scratch pad where you can make changes to objects in isolation, and you can discard the changes without affecting other contexts. If you do need to synchronize changes between contexts, how a change should be handled depends on the user-visible semantics you want in the second context, and on the state of the objects in the second context.

    Consider an application with two managed object contexts and a single persistent store coordinator. If a user deletes an object in the first context (moc1), you may need to inform the second context (moc2) that an object has been deleted. In all cases, moc1 automatically posts an NSManagedObjectContextDidSaveNotification notification via the NSNotificationCenter that your application should register for and use as the trigger for whatever actions it needs to take. This notification contains information not only about deleted objects, but also about changed objects. You need to handle these changes because they may be the result of the delete. Most of these types of changes involve transient relationships or fetched properties.

    Code for Context 1

    First, let’s look at the context setter methods. Whenever other contexts save, we want to make sure our own context updates on their saves. Thus we add an addObserver to observe saves from other contexts. Whenever other contexts save, the message NSManagedObjectContextDidSaveNotification gets sent, and we capture it like so:

    What this means is that whenever object self.privateQueueContext2 sends a message name NSManagedObjectContextDidSaveNotification, then let’s call custom method mergeChangesFromContext2.

    Note that for the object parameter, if you can it to the sender of the notification such as self.privateQueueContext2, then we will then only be notified of self.privateQueueContext2’s events.

    If we set to “nil” you will get all notification of this type (regardless who sent them).

    In our particular case, we set the object parameter to context 2, so that we can be updated on whatever context 2 just did, or is doing.

    The custom method gets called whenever context 2 saves, because we as context 1, wants to merge changes from context 2 if and when context 2 does save. We do a simple check that if the notification is from context 2, then we simply have our context 1 merge via the method mergeChangesFromContextDidSaveNotification method:

    Run the program, add your bulk of People object. Then Display them. You’ll see the first object which is 0th index.

    reportOnAllPeopleToLog method called
    2015-10-27 11:17:59.555 CoreData2[49227:5232602] ———— RESULTS FROM DATABASE ————
    2015-10-27 11:17:59.556 CoreData2[49227:5232602] There are 10 number of entries so far
    2015-10-27 11:17:59.556 CoreData2[49227:5232602] 0 —————-
    2015-10-27 11:17:59.556 CoreData2[49227:5232602] firstName = remark: 1445969859.502338
    2015-10-27 11:17:59.557 CoreData2[49227:5232602] lastName = 1445969859.502338
    2015-10-27 11:17:59.557 CoreData2[49227:5232602] object address is: 0x7fd358d8f710
    2015-10-27 11:17:59.558 CoreData2[49227:5232602] 1 —————-
    2015-10-27 11:17:59.558 CoreData2[49227:5232602] firstName = remark: 1445969859.822105
    2015-10-27 11:17:59.558 CoreData2[49227:5232602] lastName = 1445969859.822105
    2015-10-27 11:17:59.559 CoreData2[49227:5232602] object address is: 0x7fd358d83d40


    etc.

    Press button Context 1, Change to Ricky
    Press button Context 2, Change to Shirley
    Press Context 2 save
    Press Context 1 save.

    You’ll then see that Context’s RICKY is the latest save

    result:


    reportOnAllPeopleToLog method called
    2015-10-27 11:19:53.481 CoreData2[49227:5232602] ———— RESULTS FROM DATABASE ————
    2015-10-27 11:19:53.481 CoreData2[49227:5232602] There are 10 number of entries so far
    2015-10-27 11:19:53.481 CoreData2[49227:5232602] 0 —————-
    2015-10-27 11:19:53.481 CoreData2[49227:5232602] firstName = RICKY
    2015-10-27 11:19:53.481 CoreData2[49227:5232602] lastName = 1445969859.502338
    2015-10-27 11:19:53.481 CoreData2[49227:5232602] object address is: 0x7fd358c31a90
    2015-10-27 11:19:53.482 CoreData2[49227:5232602] 1 —————-


    etc

    The result is now correct. When context 2 saved Shirley, context 1 merged itself with context 2’s changes, and thus when our context 1 saves, it will see that the persistent store value and its snapshot value are both “Shirley”, and thus goes on to save its own changes of “Ricky”. Thus, after the save, we see that the value “Ricky” is reflected in the database.

    Some Upkeep

    However, this only applies for context 1 merging if and when context 2 saves. What if context 2 need to merge on what context 1 does? That means we have to do the same thing for context 2.

    Also, what if we have x number of contexts? That means for whatever context n that’s saving, we just make sure all other contexts merge with the saving context.

    Notice object is set to nil in order to observe NSManagedObjectContextDidSaveNotification messages from any object. Then in our mergeChanges custom method, we simply make all contexts merge with the saving context.

    and…

    Using the Queue and performing your edits and saves via blocks

    Apple states:
    [A context] assumes the default owner is the thread or queue that allocated it—this is determined by the queue that calls its init method. You should not, therefore, initialize a context on one queue then pass it to a different queue.

    This means that in our custom setter method for a context, we create the context with an init to a concurrency queue type. This means default owner of privateQueueContext is the queue used via the init:

    Hence privateQueueContext and the init-ed queue are now pinned together. This pattern is thread confinement or isolation.

    We created privateQueueContext with this queue, and must remember to always use privateQueueContext with this queue.

    For example, say we have a task: “use privateQueueContext to get a Person object to manipulate and later save into Core Data”. We want to queue this task because we’re doing this 10,000 times and needs to be run on a background. We queue this task on privateQueueContext because privateQueueContext is what is involved.

    Notice we use privateQueueContext on all. If in the task of fetching the Object using privateQueueContext but queueing the task on say privateQueueContext2 (which has its own queue via an init), then we have “have violated thread confinement by exposing the MOC object reference to two queues. Simple. Don’t do it. Don’t cross the streams.” (http://stackoverflow.com/questions/4800889/what-does-apple-mean-when-they-say-that-a-nsmanagedobjectcontext-is-owned-by-the)

    Part of the reason is because multiple queues process tasks concurrently. So whatever context data you are executing in queue A, may also be executed in queue B at the same time. If you were to confine tasks to its attached queue, then no context data will ever be shared because each task is processed one after another via FIFO.

    furthermore

Core Data Stack #1 – everything on main queue

https://blog.codecentric.de/en/2014/11/concurrency-coredata/

Everything on Main Queue

Create a iOS project and check “using Core Data”.

This is how it works:

basic_core_data_diagram

At the most basic level we have a CoreDataStack class.
In its implementation file, we first have:

NSManagedObjectModel – Managed Object Model

We start with the managed object model.

  • Essentially, it is the schema of our model.
  • Our model comes from the .momd file. In xcode, you can create your model and it will save to the .momd file.
  • Then we load it into a NSURL, which in turn is used to initialize a NSManagedObjectModel object.

NSPersistentStoreCoordinator – Persistent Store Coordinator

The persistent store coordinator is responsible for coordinating access to multiple persistent object stores. As an iOS developer you will never directly interact with the persistent store coordinator and, in fact, will very rarely need to develop an application that requires more than one persistent object store. When multiple stores are required, the coordinator presents these stores to the upper layers of the Core Data stack as a single store.

This is essentially the database connection. It coordinates between our model and a .sqlite file.

The class has attribute that points to our previous defined NSManagedObjectModel. Then it stores a NSURL to a .sqlite file. From there on, it is used by either one or many NSManagedObjectContexts in order to do DB operations.

NSManagedObjectContext – managed object context

This is the scratch pad for what goes into and comes out of the database. We use this to do many operations, then use save context, predicates, and other special operations to make changes to the database. There can be either 1 or more context used at the same time.

Full Source

CoreDataStack.h

CoreDataStack.m

Inserting into Core Data

Notice this method:

insertNewObjectForEntityForName returns a NSManagedObject * for you to manipulate. All you have to do is set the attributes of the object and then call the saveContext method.

NSManagedObject are the objects that are created by your application code to store data. A managed object can be considered as a row or a record in a relational database table. For each new record to be added, a new managed object must be created to store the data. Similarly, retrieved data will be returned in the form of managed objects, one for each record matching the defined retrieval criteria. Managed objects are actually instances of the NSManagedObject class, or a subclass thereof. These objects are contained and maintained by the managed object context.

When NSEntityDescription returns an object for you to insert. All you have to do is set the attributes of the object and then call the saveContext method.

Every object that is returned to you by the method insertNewObjectForEntityForName will be monitored by your context. Once you finish updating those objects, and you call saveContext, your context will check up on those objects and then save them accordingly.

Group changes together

However, calling saveContext for every change takes a bit longer because you are having the persistent store coordinator communicate with the database off of one change. You can group your changes together, and then tell your context to save once.

The Downside

While this stack is very simplistic, the downside is that if you record large amount of data, the UI will be unresponsive because you are running off of the main thread.

coredata-ui-clogged

For example, in our example, we have a for loop of 10. Change it to 10,000, and try to play with the UI controls on your viewController. They won’t work because your main thread is busy processing the 10,000 core data operations.