Это потому, что задача запускается асинхронно, поэтому метод вернется до token
даже назначен.
То, что вы должны сделать, это передать блок завершения этому методу и позвонить в него, как только у вас будет токен. Таким образом, вы не блокируете основной поток, пока выполняется запрос.
Вот как вы можете сделать это:
- (void)extractTokenFromURL:(NSURL *)tokenURL completion:(void (^)(NSString *token, NSError* error))completion {
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
[[session dataTaskWithURL:self.tokenURL
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
if (httpResp.statusCode == 200) {
NSString *token = // ...;
if (token) { // we have a valid token
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(token, nil);
});
}
} else if (completion) {
// create an error indicating why the token is not valid
NSError *error = // ...;
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, error);
});
}
}
} else if (completion) {
// send the http error. you could also wrap it on your own error domain and code
dispatch_async(dispatch_get_main_queue(), ^{
completion(nil, error);
});
}
}] resume];
}
Вы также можете иметь два разных блока: один для успеха, а другой - для неудачи.