سؤال

من الأسئلة الأخرى ، يبدو أن كل ما علي فعله هو إضافة __block أمام متغيرتي ، ومع ذلك ، لا يبدو أنه يعمل من أجلي.

أثناء داخل الكتلة ، يتم تعيين الرمز المميز بشكل صحيح عند فحصه باستخدام NSLog (). إذا قمت بفحصها مرة أخرى قبل إرجاع الرمز المميز ؛ يصبح فارغا.

- (NSString *)extractTokenFromURL:(NSURL *)tokenURL
{
__block NSString *token = nil;

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 *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSRange divRange = [content rangeOfString:@"<div id='token' style='display:none;'>" options:NSCaseInsensitiveSearch];
            if (divRange.location != NSNotFound) {
                NSRange endDivRange;
                endDivRange.location = divRange.length + divRange.location;
                endDivRange.length   = [content length] - endDivRange.location;
                endDivRange = [content rangeOfString:@"</div>" options:NSCaseInsensitiveSearch range:endDivRange];

                if (endDivRange.location != NSNotFound) {
                    divRange.location += divRange.length;
                    divRange.length  = endDivRange.location - divRange.location;

                    dispatch_async(dispatch_get_main_queue(), ^{
                        token = [content substringWithRange:divRange];
                    });
                }
            }
        }
    }
}] resume];

return token;
}
هل كانت مفيدة؟

المحلول

ذلك لأن المهمة يتم تشغيلها بشكل غير متزامن ، وبالتالي فإن الطريقة ستعود من قبل 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];
}

يمكنك أيضًا الحصول على كتلتين مختلفتين: واحدة للنجاح والآخر للفشل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top