[EDIT: I originally thought this issue was about the Obj-C interface]
The first app I'm testing with ClassKit is Objective-C.
So far I have all of the activities showing up as expected within the SchoolWork app. I can create a task, add an activity and post it to the student as expected.
I can then log in as the student (using settings to switch to student mode), and restart the SchoolWork app. I see the task and can initiate it just fine. My app is launched, and the requested task is started.
From my logs I can see that the activity is started, and that as the student traverses the activity, the progress is increased, and at the end, when the activity is ended, a score, and several other Quantity items are added. They all look fine when traced from my app.
My problem is that even though the changes to the activity are being logged fine, and the act of saving the state produces no errors, the SchoolWork app does not show that the task/activity was started, and none of the progress or quantity items are shown.
When I use the sample GreatPlays app in the same way it works as expected - sometimes.
Before I try to dig further, does anyone have this working in Objective-C? Can you get the results shown within the SchoolWork app?
UPDATE: I've tried any number of combinations; removing all CLSActivityItem objects, reordering them, etc. Then I noted that even activities created for GreatPlays don't always work either, so perhaps it's a more generalised issue with the interface to SchoolWork. I haven't yet found a reproducible pattern.
Answering my own question.
I pulled my interface code out into a test app and stepping through it all over again, I discovered that when I began or ended an activity, I was submitting the identifier as received by the AppDelegate method:
- (BOOL) application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * _Nullable))restorationHandler;Noting in the GreatPlays sample code:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
if userActivity.isClassKitDeepLink,
let identifierPath = userActivity.contextIdentifierPath {
// The first element of the identifier path is the main app context, which we don't need, so drop it.
return navigate(to: Array(identifierPath.dropFirst()))
}
return false
}That comment is really important. If you don't drop the first element, and use that path when you call:
CLSDataStore.shared.mainAppContext.descendant(matchingIdentifierPath: identifierPath)Then the context won't be found.
So having now changed my code to drop that first element, I'm seeing results in the SchoolWork app which is great.
I'm still seeing errors when ever I try to make calls to
CLSDataStore.shared.savesuch as:
2018-05-01 22:53:37.847296+1000 TestClassKit[58240:4714131] startActivityWith: Unable to save: Error Domain=com.apple.ClassKit Code=4 "Saving object not allowed." UserInfo={NSLocalizedDescription=Saving object not allowed., CLSErrorObjectKey=<CLSActivity: 0x1016d9b90> (objectID: 884C8BC1-FF09-4A1A-B386-27B5B3EC9BC8) (dateCreated: 1/5/18, 10:53 pm) (dateLastModified: 1/5/18, 10:53 pm) (progress: 0.00) (duration: 0.00) (primary-item-id: (null))}
I haven't worked out what these are about yet. The errors aren't entirely helpful or informative.