从请求中获取数据到主线程

Get data from a request to the main thread

我对 Objective C 和移动开发还很陌生。我想在此会话之外执行获取和使用响应,谁能告诉我该怎么做?

现在我收到错误“使用未声明的标识符 'username'

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"GET"];NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    
    NSRange rangeUsername = [requestReply rangeOfString:@"<username>"];
    NSString *username = [requestReply substringFromIndex:rangeUsername.location];
    username = [username stringByReplacingOccurrencesOfString:@"<username>" withString:@""];
    username = [username stringByReplacingOccurrencesOfString:@"</username>" withString:@""];
    
    NSRange rangeDomain = [requestReply rangeOfString:@"<SIP_domain>"];
    NSString *domain = [requestReply substringFromIndex:rangeDomain.location];
    domain = [domain stringByReplacingOccurrencesOfString:@"<SIP_domain>" withString:@""];
    domain = [domain stringByReplacingOccurrencesOfString:@"</SIP_domain>" withString:@""];
}] resume];

NSLog(@"Username: %@", username);
NSLog(@"Domain: %@", domain);

dataTaskWithRequest 方法 异步运行, 即稍后运行。你不能只引用块外的变量。

典型的解决方案是为执行此请求的方法提供一个块参数,一个完成处理程序,并在 dataTaskWithRequest.

的异步块内调用完成处理程序

例如,您可能有:

- (void)performRequestWithURL:(NSURL *)url completion:(void (^ _Nonnull)(NSString *username, NSString *domain, NSError *error))completion {
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    NSURLSession *session = [NSURLSession sharedSession];

    [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(nil, nil, error);
            });
            return;
        }

        NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

        NSRange rangeUsername = [requestReply rangeOfString:@"<username>"];
        NSString *username = [requestReply substringFromIndex:rangeUsername.location];
        username = [username stringByReplacingOccurrencesOfString:@"<username>" withString:@""];
        username = [username stringByReplacingOccurrencesOfString:@"</username>" withString:@""];

        NSRange rangeDomain = [requestReply rangeOfString:@"<SIP_domain>"];
        NSString *domain = [requestReply substringFromIndex:rangeDomain.location];
        domain = [domain stringByReplacingOccurrencesOfString:@"<SIP_domain>" withString:@""];
        domain = [domain stringByReplacingOccurrencesOfString:@"</SIP_domain>" withString:@""];

        dispatch_async(dispatch_get_main_queue(), ^{
            completion(username, domain, nil);
        });
    }] resume];
}

然后这样称呼它:

[self performRequestWithURL:url completion:^(NSString *username, NSString *domain, NSError *error) {
    if (error) {
        NSLog(@"error = %@", error);
        return;
    }

    // use `username` and `domain` here ...
}];

// ... but not here, because the above runs asynchronously