App settings bundle not showing up in settings app

2019-06-13 16:15发布

When my app launches, a modal view displays to the user and includes an option to adjust a setting in the Settings app. If this option is selected, I use openURL as follows:

if (&UIApplicationOpenSettingsURLString != NULL) {
        NSURL *appSettings = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:appSettings];
}

This successfully redirects the user to my app's settings in the Settings app. The problem is that the only setting that appears to the user is the "Use Cellular Data" radio button. My settings from the root.plist are nowhere to be found. In all subsequent visits to this view in the Settings app, the root.plist settings all load correctly.

My theory is that this is a timing issue and that my app's root.plist has not yet been loaded in the Settings app for some reason. Does anyone know if this is the case? Can I force it to load somehow? It's awkward and confusing to direct the user to non-existent settings.

1条回答
forever°为你锁心
2楼-- · 2019-06-13 17:11

At the following link:

NSUserDafaults reading Root.plist got a nil value

Someone stated that "The values from settings.bundle do not actually load to NSUserDefaults until the user opens the settings for the first time. By default, they are off. Once the user opens the settings bundle, they will fill in for you."

and I believe some solutions were proposed here:

Can you make the settings in Settings.bundle default even if you don't open the Settings App

Such as this one from @Lawrence Johnston

- (void)registerDefaultsFromSettingsBundle {
    [[NSUserDefaults standardUserDefaults] registerDefaults:[self defaultsFromPlistNamed:@"Root"]];
}

- (NSDictionary *)defaultsFromPlistNamed:(NSString *)plistName {
    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
    NSAssert(settingsBundle, @"Could not find Settings.bundle while loading defaults.");

    NSString *plistFullName = [NSString stringWithFormat:@"%@.plist", plistName];

    NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:plistFullName]];
    NSAssert1(settings, @"Could not load plist '%@' while loading defaults.", plistFullName);

    NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
    NSAssert1(preferences, @"Could not find preferences entry in plist '%@' while loading defaults.", plistFullName);

    NSMutableDictionary *defaults = [NSMutableDictionary dictionary];
    for(NSDictionary *prefSpecification in preferences) {
        NSString *key = [prefSpecification objectForKey:@"Key"];
        id value = [prefSpecification objectForKey:@"DefaultValue"];
        if(key && value) {
            [defaults setObject:value forKey:key];
        } 

        NSString *type = [prefSpecification objectForKey:@"Type"];
        if ([type isEqualToString:@"PSChildPaneSpecifier"]) {
            NSString *file = [prefSpecification objectForKey:@"File"];
            NSAssert1(file, @"Unable to get child plist name from plist '%@'", plistFullName);
            [defaults addEntriesFromDictionary:[self defaultsFromPlistNamed:file]];
        }        
    }

    return defaults;
}
查看更多
登录 后发表回答