2015-05-06 2 views
0

Я думаю, что этот вопрос будет очень сложным спросить, так что медведь со мной, и если это не имеет смысла, просто дайте мне знать.iOS Пользовательские настройки сохранности и обновления

Начну с объяснения ситуации, а затем покажу код. Таким образом, у меня есть приложение, которое имеет массив настроек по умолчанию для отображения на панели пользователя. Пользователь может изменить эти параметры, чтобы включить или отключить определенные элементы, которые отображаются на панели управления.

Я хочу иметь возможность обновлять настройки «по умолчанию», и если я добавлю новый элемент, он автоматически обновит настройки пользователя, но не перезапишет их личную настройку включения/выключения.

Так что у меня этот массив словарей, «по умолчанию»:

dashboardItems = @[ 
        @{ 
         @"id" : @"1", 
         @"order" : @"0", 
         @"title" : @"Steps Traveled", 
         @"unit" : @"", 
         @"type" : HKQuantityTypeIdentifierStepCount, 
         @"sampleUnit" : @"count", 
         @"enabled" : @"1" 
        }, 
        @{ 
         @"id" : @"2", 
         @"order" : @"1", 
         @"title" : @"Flights Climbed", 
         @"unit" : @"", 
         @"type" : HKQuantityTypeIdentifierFlightsClimbed, 
         @"sampleUnit" : @"count", 
         @"enabled" : @"1" 
        }, 
        @{ 
         @"id" : @"3", 
         @"order" : @"2", 
         @"title" : @"Distance Traveled", 
         @"unit" : @"mi", 
         @"type" : HKQuantityTypeIdentifierDistanceWalkingRunning, 
         @"sampleUnit" : @"mi", 
         @"enabled" : @"1" 
        }, 
        @{ 
         @"id" : @"4", 
         @"order" : @"3", 
         @"title" : @"Active Calories", 
         @"unit" : @"", 
         @"type" : HKQuantityTypeIdentifierActiveEnergyBurned, 
         @"sampleUnit" : @"kcal", 
         @"enabled" : @"1" 
        }, 
        @{ 
         @"id" : @"5", 
         @"order" : @"4", 
         @"title" : @"Weight", 
         @"unit" : @"lbs", 
         @"type" : HKQuantityTypeIdentifierBodyMass, 
         @"sampleUnit" : @"lb", 
         @"enabled" : @"1" 
        }, 
        @{ 
         @"id" : @"6", 
         @"order" : @"5", 
         @"title" : @"Cycling", 
         @"unit" : @"mi", 
         @"type" : HKQuantityTypeIdentifierDistanceCycling, 
         @"sampleUnit" : @"mi", 
         @"enabled" : @"1" 
        }, 
        @{ 
         @"id" : @"7", 
         @"order" : @"6", 
         @"title" : @"Heart Rate", 
         @"unit" : @"BPM", 
         @"type" : HKQuantityTypeIdentifierHeartRate, 
         @"sampleUnit" : @"count/min", 
         @"enabled" : @"1" 
        }, 
        @{ 
         @"id" : @"8", 
         @"order" : @"7", 
         @"title" : @"BMI", 
         @"unit" : @"", 
         @"type" : HKQuantityTypeIdentifierBodyMassIndex, 
         @"sampleUnit" : @"count", 
         @"enabled" : @"1" 
        } 
     ]; 

Таким образом, пользователь может использовать переключатель, чтобы изменить включен с 1 на 0 или наоборот, чтобы включить или выключить вещь, со мной до сих пор?

Когда пользователь подписывает приложение, он сохраняет настройки «по умолчанию» на NSUserDefaults, а также на живой сервер для резервного копирования, если пользователь когда-либо удаляет приложение.

Если пользователь выходит из системы или удаляет приложение, при следующем входе в систему мы проверяем, есть ли у них в настоящее время, и NSUserDefaults сохранен, если мы не вытаскиваем с сервера.

Затем я сравниваю 2 массива, чтобы увидеть, были ли какие-либо элементы изменены или добавлены в «значения по умолчанию», это лучший способ сделать это?

//here we need to check if the user does not have any preferences saved, if not pull them from Parse. 
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

NSMutableArray *dashboardItems = [defaults objectForKey:@"dashboardItems"]; 

if (dashboardItems == nil) { 

    //user has no preferences so load them in 
    dashboardItems = [NSJSONSerialization JSONObjectWithData:[user[@"preferences"] dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; 

    [defaults setObject:dashboardItems forKey:@"dashboardItems"]; 
    [defaults synchronize]; 

} 

//compare current preferences against default to see if any new items were changed 
NSArray *defaultPreferences = [[PreferencesManager sharedManager] dashboardItems]; 

for (NSDictionary *item in defaultPreferences) { 

    for (NSDictionary *userItem in dashboardItems) { 

     if ([item[@"id"] isEqualToString:userItem[@"id"]]) { 

      //we have a match, compare name and change if necessary 
      if (![item[@"title"] isEqualToString:userItem[@"title"]]) { 

       //set user's item title to default title 
       [userItem setValue:item[@"title"] forKey:@"title"]; 

      } 

     } else { 

      //we did not find this in user preferences, so add it 
      [dashboardItems addObject:item]; 

     } 

    } 


} 

//save defaults 
[defaults setObject:dashboardItems forKey:@"dashboardItems"]; 
[defaults synchronize]; 

Если мне нужно прояснить что-либо еще, пожалуйста, просто дайте мне знать.

Спасибо!

+0

Так как это работает код, и вы, кажется, хотят обзор кода рабочего кода, вы должны отправить это на http://codereview.stackexchange.com вместо Вот. – rmaddy

+0

Итак, в чем вопрос? –

+0

Вопрос в том, как я должен сравнивать оба массива, или есть более эффективный способ сделать это? Есть ли что-нибудь, что мне нужно иметь в виду, когда делаешь это так? Я не хочу перезаписывать личные настройки пользователя, поэтому я предполагаю, что мне нужно проверить каждую пару ключей/значений в словаре по отдельности и при необходимости изменить. –

ответ

1

Я хотел бы начать получать все настройки по умолчанию, а затем заменить те, что есть совпадение в сохраненных настройках пользователя:

NSMutableArray *defaultSettings = [@[] mutableCopy]; 
NSArray *userSettings = @[]; 
for (NSInteger i = 0; i < defaultSettings.count; i++) { 
    NSDictionary *setting = defaultSettings[i]; 
    NSInteger index = [userSettings indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { 
     NSDictionary *userSetting = obj; 
     *stop = [setting[@"title"] isEqualToString:userSetting[@"title"]]; 
     return *stop; 
    }]; 
    if (index != NSNotFound) { 
     // Found matching setting 
     defaultSettings[i] = userSettings[index]; 
    } 
} 

[defaults setObject:defaultSettings forKey:@"defaultSettings"]; 
[defaults synchronize]; 

Но если бы я тебя, я хотел бы использовать NSDictionary из NSDictionary и использование ключ как идентификатор. Было бы сделал тот же процесс намного проще:

NSDictionary *defaultSettings = @{ 
            @"1": @{@"order": @"0", @"title": @"Steps traveled", @"enabled": @"0"}, 
            @"2": @{@"order": @"1", @"title": @"Flights Climbed", @"enabled": @"0"}, 
            @"3": @{@"order": @"2", @"title": @"Distance Traveled", @"enabled": @"0"} 
            }; 
NSMutableDictionary *mutableDefaultSettings = [defaultSettings mutableCopy]; 
NSDictionary *userSettings = @{ 
           @"2": @{@"order": @"1", @"title": @"Flights Climbed", @"enabled": @"1"} 
           }; 

for (NSString *id in userSettings.allKeys) { 
    mutableDefaultSettings[id] = userSettings[id]; 
} 

[defaults setObject:mutableDefaultSettings forKey:@"dashboardItems"]; 
[defaults synchronize]; 
+0

Да, я думал об использовании словаря словарей, поэтому он был более ассоциативным, но не был уверен, могу ли я хранить его таким образом в NSUserDefaults. –

+0

Вы определенно можете хранить NSDictionary в NSUserDefaults. Поскольку у вас есть ключевой «порядок», который дает вам отображаемый порядок (я думаю), вам не нужно использовать NSArray. Воспользуйтесь NSDictionary для доступа к элементам ключом! – Rufel

Смежные вопросы