PhilipsHue / PhilipsHueSDK-iOS-OSX

The Software Development Kit for Philips Hue on iOS and OS X (beta)
579 stars 169 forks source link

Sharing PHAuthentication Between Build Targets #87

Closed joeblau closed 4 years ago

joeblau commented 9 years ago

Is there a way to share the Authentication information across build targets? Right now I need to re-authenticate to the Bridge in my today widget after I've already authenticated in my app.

In the documentation it says that you need to use startPushlinkAuthentication and then link to your light. The problem is that this information is not stored between build targets (App, Today Widget, Apple Watch) so developers are required to reInitialize a push link connection in each target app. I don't know where this authentication information is currently stored, but if there was either a way to use a shared group or an API to load PHAuthentication information from my own group, that would be very helpful.

agg23 commented 9 years ago

I'm experiencing exactly this same issue, and my poking around in the framework has found nothing of use. Supporting authentication like this is a must with iOS extensions.

joeblau commented 9 years ago

@agg23 My roommate and I are about to re-write the parts of this library that we need in Swift. This SDK's design isn't really optimal for doing anything other than basic interactions with the bridge.

philwebster commented 9 years ago

The authentication information and bridge resource cache is stored in the app's plist file. The way I'm sharing the configuration to a watch app and other extensions is by creating an app group ("group.hue" in the code below) and updating the shared preferences whenever there's a heartbeat. The Hue sdk looks in the standard user defaults for whatever target is running, so we copy the shared settings to the current target's defaults. I do this before creating the sdk object in the willActivate method for the watch extension.

Here's the code in the phone app:

    NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.hue"];
    NSData *cacheData = [[NSUserDefaults standardUserDefaults] objectForKey:@"phBridgeResourcesCache"];
    NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"uniqueGlobalDeviceIdentifier"];
    [sharedDefaults setObject:cacheData forKey:@"phBridgeResourcesCache"];
    [sharedDefaults setObject:deviceID forKey:@"uniqueGlobalDeviceIdentifier"];
    [sharedDefaults synchronize];

The watch app:

    NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.hue"];
    NSData *cacheData = [sharedDefaults dataForKey:@"phBridgeResourcesCache"];
    NSString *deviceID = [sharedDefaults stringForKey:@"uniqueGlobalDeviceIdentifier"];
    [[NSUserDefaults standardUserDefaults] setObject:cacheData forKey:@"phBridgeResourcesCache"];
    [[NSUserDefaults standardUserDefaults] setObject:deviceID forKey:@"uniqueGlobalDeviceIdentifier"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    self.phHueSDK = [[PHHueSDK alloc] init];
    [self.phHueSDK startUpSDK];
    [self.phHueSDK enableLogging:YES];

    PHBridgeResourcesCache *cache = [PHBridgeResourcesReader readBridgeResourcesCache];
    if (cache != nil && cache.bridgeConfiguration != nil && cache.bridgeConfiguration.ipaddress != nil) {
        [self.phHueSDK enableLocalConnection];
    } else {
        NSLog(@"need to set up with iPhone first");
    }

Other issues I ran into:

This is not the greatest solution and I'm working on creating a shared framework that can be used between multiple targets. For a good example of how this is done, check out Apple's Lister sample project.

joeblau commented 9 years ago

Thanks for digging this up. I was just about to re-write this library in a few weeks.

wimhaanstra commented 9 years ago

Thanks a lot, will try this out.

Still, the library feels really unsupported. Too bad, but I am also looking in writing my own library for this.

pverh commented 9 years ago

Sorry for the late response. While I cannot promise anything, we are currently looking into a way to make it easier for extensions to use the SDK for our next release.

In the mean time the approach mentioned by @philwebster can be used as this is the correct way of doing this on the current SDK version.

reprotector commented 7 years ago

@pverh @philwebster @joeblau What's the current status of it?

I can't see uniqueGlobalDeviceIdentifier on NSUserDefaults anymore, so it isn't sharing the authentication between targets. It's asking for pushlinking again. There's anything I'm missing there?

joeblau commented 7 years ago

@reprotector We stopped working on the project that we were building so I have no idea anymore.

reprotector commented 7 years ago

@joeblau :( Thanks for answering here