Как выполнить строку кода ТОЛЬКО после завершения метода?

У меня есть метод getSpotifyProductTypeWithSession:(SPTSession *)session что я звоню в viewDidLoad, и я хочу, чтобы код под ним был выполнен только один раз getSpotifyProductTypeWithSession:(SPTSession *)session закончил Как мне это сделать? Вот мой код ниже.

-(void)viewDidLoad{

SPTAuth *auth = [SPTAuth defaultInstance];

    [self getSpotifyProductTypeWithSession:auth.session];


        BOOL hasPremium = [[NSUserDefaults standardUserDefaults] boolForKey:@"hasPremium"];

        if (hasPremium) {
            [FireStarter setSpotifyHasPremium];
        } else {
            [FireStarter setSpotifyHasFree];
        }

}

-(void)getSpotifyProductTypeWithSession:(SPTSession *)session{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [SPTUser requestCurrentUserWithAccessToken:session.accessToken callback:^(NSError *error, SPTUser *user) {

        [defaults setBool:NO forKey:@"hasPremium"];
        [defaults synchronize];

        switch (user.product) {
            case SPTProductFree:
                [defaults setBool:NO forKey:@"hasPremium"];
                [defaults synchronize];
                break;
            case SPTProductPremium:
                [defaults setBool:YES forKey:@"hasPremium"];
                [defaults synchronize];
                break;
            case SPTProductUnlimited:
                [defaults setBool:YES forKey:@"hasPremium"];
                [defaults synchronize];
            default:

                break;
        }
    }];

    NSLog(@"%@",[defaults objectForKey:@"hasPremium"]);
}

2 ответа

Решение

Вы хотите добавить параметр обработчика завершения в свой getSpotifyProductTypeWithSession метод. Затем вы можете переместить свой код в обработчик завершения. Было бы также полезно, чтобы обработчик завершения сообщал вам результат, поэтому вам не нужно проверять NSUserDefaults снова.

Вот добавленный параметр:

-(void)getSpotifyProductTypeWithSession:(SPTSession *)session completion:(void (^)(BOOL hasPremium))completion {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [SPTUser requestCurrentUserWithAccessToken:session.accessToken callback:^(NSError *error, SPTUser *user) {
        BOOL hasPremium = NO;

        switch (user.product) {
            case SPTProductFree:
                hasPremium = NO;
                break;
            case SPTProductPremium:
            case SPTProductUnlimited:
                hasPremium = YES;
                break;
        }

        [defaults setBool:hasPremium forKey:@"hasPremium"];

        if (completion) {
            completion(hasPremium);
        }
    }];
}

И вот как вы это называете:

[self getSpotifyProductTypeWithSession:auth.session completion:^(BOOL hasPremium) {
    if (hasPremium) {
        [FireStarter setSpotifyHasPremium];
    } else {
        [FireStarter setSpotifyHasFree];
    }
}];

Там могут быть некоторые опечатки. Этот код не был скомпилирован и протестирован, но он дает идею.

Чтобы хорошо поработать с методами, которые выполняют асинхронную работу и принимают блоки завершения, вы должны использовать тот же подход в своем коде. Таким образом, вы можете объявить что-то вроде:

-(void)getSpotifyProductTypeWithSession:(SPTSession *)session completion:(void (^)(NSError *))completion {
    // ... OP code
    [SPTUser requestCurrentUserWithAccessToken:session.accessToken callback:^(NSError *error, SPTUser *user) {
        // if there's an error
        if (error) completion(error);
        // ....more OP code
        // at the end
        completion(nil);   // we're done with no error
    }];
}

Теперь ваш призыв к этому следует той же схеме...

-(void)viewDidLoad{
    SPTAuth *auth = [SPTAuth defaultInstance];
    [self getSpotifyProductTypeWithSession:auth.session completion:^(NSError *)error {
        BOOL hasPremium = [[NSUserDefaults standardUserDefaults] boolForKey:@"hasPremium"];
       // and so on...
    }];
Другие вопросы по тегам