NSUserDefaults not working on Xcode beta with Watch OS2

前端 未结 5 1753
一个人的身影
一个人的身影 2020-11-27 07:02

I just installed the latest beta of Xcode to try Swift 2 and the improvements made to the Apple Watch development section.

I\'m actually having an h

5条回答
  •  心在旅途
    2020-11-27 07:34

    NSUserDefaults (even with an App Groups) don't sync between the iPhone and the Watch in watchOS 2. If you want to sync settings from either your iPhone app or the Settings-Watch.bundle, you have to handle the syncing yourself.

    I've found that using WatchConnectivity's user info transfers works really well in this case. Below you'll find an example of how you could implement this. The code only handles one-way syncing from the phone to the Watch, but the other way works the same.

    In the iPhone app:
    1) Prepare dictionary of settings that need to be synced

    - (NSDictionary *)exportedSettingsForWatchApp  
    {  
        NSUserDefaults *userDefaults = [self userDefaults]; // the user defaults to sync  
    
        NSSet *keys = [self userDefaultKeysForWatchApp]; // set of keys that need to be synced  
        NSMutableDictionary *exportedSettings = [[NSMutableDictionary alloc] initWithCapacity:keys.count];  
    
        for (NSString *key in keys) {  
            id object = [userDefaults objectForKey:key];  
    
            if (object != nil) {  
                [exportedSettings setObject:object forKey:key];  
            }  
        }  
    
        return [exportedSettings copy];  
    }  
    

    2) Determine when the settings need to be pushed to the Watch
    (not shown here)

    3) Push the settings to the Watch

    - (void)pushSettingsToWatchApp  
    {  
        // Cancel current transfer  
        [self.outstandingSettingsTransfer cancel];  
        self.outstandingSettingsTransfer = nil;  
    
        // Cancel outstanding transfers that might have been started before the app was launched  
        for (WCSessionUserInfoTransfer *userInfoTransfer in self.session.outstandingUserInfoTransfers) {  
            BOOL isSettingsTransfer = ([userInfoTransfer.userInfo objectForKey:@"settings"] != nil);  
            if (isSettingsTransfer) {  
                [userInfoTransfer cancel];  
            }  
        }  
    
        // Mark the Watch as requiring an update  
        self.watchAppHasSettings = NO;  
    
        // Only start a transfer when the watch app is installed  
        if (self.session.isWatchAppInstalled) {  
            NSDictionary *exportedSettings = [self exportedSettingsForWatchApp];  
            if (exportedSettings == nil) {  
                exportedSettings = @{ };  
            }  
    
            NSDictionary *userInfo = @{ @"settings": exportedSettings };  
            self.outstandingSettingsTransfer = [self.session transferUserInfo:userInfo];  
         }  
    }  
    

    In the Watch extension:
    4) Receive the user info transfer

    - (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary *)userInfo  
    {  
        NSDictionary *settings = [userInfo objectForKey:@"settings"];  
        if (settings != nil) {  
            // Import the settings  
            [self importSettingsFromCompanionApp:settings];  
         }  
    } 
    

    5) Save the received settings to the user defaults on the Watch

    - (void)importSettingsFromCompanionApp:(NSDictionary *)settings  
    {  
        NSUserDefaults *userDefaults = [self userDefaults]; // the user defaults to sync  
    
        NSSet *keys = [self userDefaultKeysForWatchApp]; // set of keys that need to be synced  
        for (NSString *key in keys) {  
            id object = [settings objectForKey:key];  
            if (object != nil) {  
                [userDefaults setObject:object forKey:key];  
            } else {  
                [userDefaults removeObjectForKey:key];  
            }  
        }  
    
        [userDefaults synchronize];  
    }  
    

提交回复
热议问题