-
Notifications
You must be signed in to change notification settings - Fork 505
Add CloudKit discoverability permissions. #58
Comments
Thanks @evermeer, I'll look into adding this in. |
Status should be an async call then :P |
Yeah, that was about as far as I got into the implementation too :) |
What should we do when CouldNotComplete is returned ? Docs say that you should investigate the NSError returned so...Use throws ? Print the error ? Quick-dirty version done...Can someone test it ? Don't use the example app, but rather a new one since it requires entitlements on your App ID Should we add an observer for CKAccountChangedNotification ? Or is it the job of the dev to add it and use PScope's API to request if necessary ?
|
Hi, I tried adding the Quick-dirty version to a project of mine using: pod 'PermissionScope', :git => 'https://github.com/bre7/PermissionScope.git', :branch => 'wip/cloudkit' I just did a pull request to make it work in beta 6 |
I'm currently adding it to the demo at https://github.com/evermeer/EVCloudKitDao/tree/Swift2 |
Awesome, thanks for that @evermeer |
I have been thinking about the CKAccountChangedNotification. I think it should be implemented by the developer. This because he should probably also have to reset the interface to an initial state. (exit user specific screens) and there is a chance that it should be done before PermissionScope screen is shown. So the current callback functions might be too late. Or... Maybe PermissionScope could have an extra optional callback function that will be executed when it's detected that permissions could have been changed or should be reevaluated. that function could have a return value Bool that will control if PermissionScope should show again or not. |
I found some issues with this version. I will do some more tests. func showPermissionScope() {
pscope.headerLabel.text = "Setting permissions"
pscope.bodyLabel.text = "For optimal usage we need some permissions."
pscope.addPermission(PermissionConfig(type: .Notifications, demands: .Required, message: "For if you want to receive notifications that people send directly to you"))
pscope.addPermission(PermissionConfig(type: .CloudKit, demands: .Required, message: "So that other users can find you"))
pscope.show({ (finished, results) -> Void in
print("TODO: results is a PermissionsResult for each config")
if finished {
self.getUser()
}
}, cancelled: { (results) -> Void in
print("WARNING: PermissionScope was cancelled")
})
} When running this on a simulator that was just reset:
assert(configuredPermissions.filter { $0.type == config.type }.isEmpty, "Permission for \(config.type) already set") The log will show you this:
|
Yeah, it's a bug being tracked in #69.
It's a system alert so there's nothing we can do other than present a new alert first ? Which isn't very nice.
Where is the function showPermissionScope() being called from ? Because it sounds like you are trying to add a .Notifications permission again, maybe you added the call in viewDidAppear ? |
Ah, ok, for now I will wait for #69 No, it's not a system setting, it's from this line: let alert = UIAlertController(title: "\(permission) is currently disabled.",
message: "Please enable access to \(permission) in Settings",
preferredStyle: .Alert) Maybe that line is a little to generic? Another ah, I see, my bad.. The moment NSUbiquityIdentityDidChangeNotification is triggered I tried executing PermissionScope again without resetting it. I do have another issue. After restarting the app it will immediately execute the callback with finished is true but only 1 element in the results while both are required. The element is for Notifications Authorized. I expect also an entry for CloudKit Authorized. (or a finished = false) |
Oops, sorry about that. The message might need some rephrasing, @nickoneill will take a look later though imo it's fine. The only fix I can think of is using prettyDescription instead of the name itself.
Not sure why it's happening...I'll have a look later. Update: @evermeer I think I've found the problem, it was related to the computed variables (someone deleted the .Required) which is fixed in the healthkit branch. I'll merge it to cloudkit later. |
Great! I now have it working in my demo app and pushed it to GitHub. I did create a workaround for reactivating PermissionScope in the event that the NSUbiquityIdentityDidChangeNotification was called the moment the PermissionScope screen was still open. The workaround is calling the hide and then after 1 second the show. It would be nice if there was a method in PermissionScope to reinitialize everything. Do you want me to create a new issue for this? See the function reactToiCloudloginChanges in: |
Create a separate issue for it. That's the disadvantage of not having PScope as the observer itself. Everything else worked as expected using my branch ? |
Maybe I don't have this set up correctly @evermeer but this looks broken in the example project for me. I did the basics and let Xcode set up entitlements for me and requested the cloudkit permission, but the request screen is all over the place (see the screenshot below). Additionally, the results callback is called with the other non-cloudkit permissions immediately, but never called with CloudKit. So if you had requested two other permissions that were allowed but CloudKit had not, the permissions dialog would never show and the API feedback would be incorrect. I still don't have a real clear idea for how we should handle these sorts of very asynchronous permissions requests. It seems to me that we either get into a situation where the dialog is displayed and jumps away when the cloudkit permission finally returns Authorized or we wait some longer period of time before showing the dialog which defeats the purpose if you require certain permissions in part of your app. |
Mmmmh, it's probably a good idea to move CK to a new branch for the time being then. @nickoneill could you close it and open a new issue ? So we can tag it properly as a bug |
Yeah, I'm feeling a bit of pressure to get the Swift 2 stuff locked down for iOS 9. I'll move it to a cloudkit branch and pull it from this branch so we can keep things relatively stable. |
@nickoneill I have seen that screen 'glitch' before, but it's not consistent. It's always the last texts that is placed at the top of the screen. Maybe create a new issue for that? Or do you think it's Async/CloudKit related? How I think you should handle async permissions:
p.s. The current swift2 branch has a compile error. CloudKit was removed from a switch, but it's still in the Enum which makes the switch incomplete. |
Fixed. |
I remember fixing a similar visual glitch for another permission in the past, I'll have to dig into some commits to remember what the issue was. I definitely like the (Why should this default to true? I would rather people see the dialog and look at the docs to change behavior than try to use pscope and be unable because "nothing shows up", i.e. they have pending items and we defaulted to not showing them) For discussion: Thanks @bre7 for that fix, I missed that last part when I ripped cloudkit out. |
I'm kind of new to open source, so not exactly sure how to document this, but there is a problem with the 'getResultsForConfig' function and cloudKit. This is because the request for the CloudKit permission status has another asynchronous call inside of it (unlike the other permissions). Therefore the dispatch_group thinks the block is completed, when it actually has not. For example, I am requesting Notifications and CloudKit, but as soon as I answer Notifications, it returns. I think this is what it should be func getResultsForConfig(completionBlock: resultsForConfigClosure) {
var results: [PermissionResult] = []
let group: dispatch_group_t = dispatch_group_create()
for config in configuredPermissions {
dispatch_group_enter(group)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
self.statusForPermission(config.type, completion: { status in
let result = PermissionResult(type: config.type,
status: status)
results.append(result)
dispatch_group_leave(group)
})
}
}
// FIXME: Return after async calls were executed
dispatch_group_notify(group,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
print("returned results \(results)")
completionBlock(results)
}
} |
Hi @owaves, glad to have you contributing. The cloudkit stuff is still work in progress and probably a bit out of date compared to master at the moment. I think we can get rid of the dispatch_group stuff when we move to a I'm happy to accept a PR for changes to how the cloudkit branch works at the moment if you'd like to submit one, or you can take a stab at the proposed |
Reopen if there's enough user interest |
I already had given up hope that this would ever be implemented. |
For this you can use the following 2 Async calls:
Edit: Formatted code.
The text was updated successfully, but these errors were encountered: