Using Core Data with watchOS 2.0
Yes, you'll have to maintain two separate stores. If either side is a "read-only" client and the CoreData datastore is small and changes infrequently you could potentially use the transferFile WatchConnectivity API to transfer the whole store each time it changes.
CloudKit error using watchOS 3
According to Apple:
CloudKit usage is blocked on watchOS Simulators. Running any test will
throw a “Not Authenticated” error even though you are signed in via
the paired iOS Simulator. Workaround: Use CloudKit on paired devices
with watchOS 3 and iOS 10.
This is from the watchOS 3 release notes, but does not seem to be fixed yet. Just test on a real watch and everything will work fine.
Notification of changes in Core Data SQLite store between iPhone and Apple Watch app
The solution that I've found quite satisfactory was to use MMWormhole library.
It works by using CFNotificationCenter Darwin Notifications and writing/reading data files in the shared app group, which results in instant communication between an iOS app and an app extension (Watch app, today's widget, etc).
Basic code goes like this:
Wormhole initialization
wormhole = MMWormhole(applicationGroupIdentifier: appGroup, optionalDirectory: nil)
Passing data object to a wormhole
let payload = ["Key": "Value"]
wormhole.passMessageObject(payload, identifier: theSameMessageIdentifier)Listening for incoming object from a wormhole
wormhole.listenForMessageWithIdentifier(theSameMessageIdentifier) { message -> Void in
if let payloadDictionary = message as? Dictionary<String, String> {
// Do some work
}
}
It's as simple as that.
Realm database for iOS app with Watch Extension
While in watchOS 1, watch apps were shared extensions of the parent app with access to shared files, as of watchOS 2, this is no longer the case.
Apps on watchOS 2 are completely separate from their parent iOS apps (To the point where I believe they can function while the parent app is closed). As such, it's necessary for you to communicate changes made in the iOS app to the watch.
You can use WCSession
in the WatchConnectivity framework to send data between the two platforms. If you have a pre-bundled Realm file containing an initial set of data, you should be able to send the entire file over when the app initially launches. After that point, you should only send the key-value data of what changed to the watch so it remains up to date.
What is the expected lifecycle of iOS 8 App Group directories?
I also posted this on the Apple Dev forums, and got an answer back from someone in Apple developer relations. Here is what they said:
Is there any potential for the system purging this location under low disc conditions?
That won't happen.
I'm trying to determine if it is "safe" to store my app's primary core data database in this App Group location, or if I should be making copies of data there instead.
Placing your core data store in an App Group directory is perfectly reasonable.
Also, what is the intent for App Group directories?
They are there so that suites of apps can shared data. I think the clearest expression of this comes from the Mac documentation. The "App Sandbox Design Guide" says:
[...] an application can use the com.apple.security.application-groups entitlement to request access to a shared container that is common to multiple applications produced by the same development team. This container is intended for content that is not user-facing, such as shared caches or databases.
Documentation
How can I guarantee unique entries in a Core Data store in a shared app container used by both the host app and an extension?
Is there a known approach to this rather novel problem introduced by iOS 8 extensions?
Yes, it's the same approach that applies when using iCloud with Core Data: let the duplicates happen, but then go and clean them up. Both situations run the risk of creating duplicate entries, and there's no completely reliable way to prevent them. Since you have a uniqueID
key, you're in good shape as far as this is concerned.
It would be a lot easier, as Dave DeLong notes, to avoid the problem in the first place. If that's impossible, you can deal with it, with some extra work.
Finding duplicates would be something like:
NSError *error = nil;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:self.persistentStoreCoordinator];
NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:@"MyEntityName"];
[fr setIncludesPendingChanges:NO];
NSExpression *countExpr = [NSExpression expressionWithFormat:@"count:(uniqueID)"];
NSExpressionDescription *countExprDesc = [[NSExpressionDescription alloc] init];
[countExprDesc setName:@"count"];
[countExprDesc setExpression:countExpr];
[countExprDesc setExpressionResultType:NSInteger64AttributeType];
NSAttributeDescription *uniqueIDAttr = [[[[[_psc managedObjectModel] entitiesByName] objectForKey:@"MyEntityName"] propertiesByName] objectForKey:@"uniqueID"];
[fr setPropertiesToFetch:[NSArray arrayWithObjects:uniqueIDAttr, countExprDesc, nil]];
[fr setPropertiesToGroupBy:[NSArray arrayWithObject:uniqueIDAttr]];
[fr setResultType:NSDictionaryResultType];
NSArray *countDictionaries = [moc executeFetchRequest:fr error:&error];
This is pretty much the Core Data equivalent of something like this in SQL:
SELECT uniqueID, COUNT(uniqueID) FROM MyEntityName GROUP BY uniqueID;
You get an array of dictionaries, each of which contains a uniqueID
and a count of the number of times that value is used. Run through the dictionary and deal with duplicates appropriately.
I described this in more detail in a blog post. There's also a sample project from Apple that demonstrates the process, called SharedCoreData, but I believe it's only available as part of the WWDC 2012 sample code bundle. It was also described in session 227 at that conference.
Related Topics
Uibezierpath + Cashapelayer - Animate a Circle Filling Up
How to Find the Index of a Tuple Element from an Tuple Array? iOS, Swift
Swift - Set Delegate for Singleton
Create Alert Function in All View Controllers - Swift
Retrieving Uiimage from Uiimageview in Swift
iOS Swift Flood Fill Algorithm
Sorting Struct Array in Swift 4
Updating Label Takes Too Long (Swift)
Find Delegate in a Swift Array of Delegates
Swift 2 - Separating an Array into a Dictionary with Keys from a to Z
Swift - Nsdate and Last Week of Year
Modeling Sub-Collections in Mongodb Realm Sync
Firebase: Provided Bucket Does Not Match the Storage Bucket of the Current Instance in Swift
Why Is My Admob Interstitial Working Fine in Xcode Simulator But Not on My Test Devices
Ios: How to Create Expandable Tableview in Swift Without Using Third Party Libraries or Pods
iOS Swift Avplayer Inside Uiview How to Make It Work
Which View Controller Should I Pass in My Swift Native Code for a Flutter Plugin