1

有趣的编程难题...

我未能将错误初始化为零,所以下面的代码崩溃了。

    NSString *query = [NSString stringWithFormat:@"http://mysite.com/getlatest.php?a=%@", aSuiteName];
    NSURL *url = [NSURL URLWithString:query];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:10];
    [request setHTTPMethod:@"GET"];
    NSURLResponse *response = nil;
    NSError *error;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    if ( !data || error != nil ) {
        NSLog(@"Error downlading %@", error); //CRASH
        return NO;
    }

我的问题是,我怎样才能让我的服务器返回一个错误,使得 sendSynchronousRequest:returningResponse:error: 实际上收到一个错误,但仍然继续下载数据?某种非致命错误会导致错误被初始化为 NSError 对象?

这与一个类似的难题有关,我之前希望返回状态信息而不会完全失败。所以,虽然晦涩难懂,但我很想知道是否有这种技术。

虽然这是一个 Cocoa 问题,但我认为答案将在 php.ini 中。就像是

<?php

    header( set 503 error here );

    return data;

?>
4

1 回答 1

0

我通过将数据包装到一个 NSError 对象中来处理这个问题。在纯文本响应的情况下,我还将响应用作本地化描述。我使用单独的方法来评估结果是否成功。如果 URL 请求本身产生错误,我也认为是失败,并传递 URL 请求提供的 NSError。

这是从我的 ServerRequest 类中截取的:

+ (NSError *) errorForStatusCode:(NSInteger) statusCode
                     contentType:(NSString *) contentType
                textEncodingName:(NSString *) textEncodingName
                            data:(NSData *) data {

    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    if ([contentType isEqualToString:@"text/plain"]) {
        [userInfo setValue:[[NSString alloc] initWithData:data encoding:[self stringEncodingForTextEncodingName:textEncodingName]]
                    forKey:NSLocalizedDescriptionKey];
    } else if ( ... ) {
        // handle other relevant types         
    }

    return [NSError errorWithDomain:[[self class] description]
                               code:statusCode
                           userInfo:userInfo];
}

- (BOOL) statusCodeIndicatesSuccess:(NSInteger) statusCodeValue {
    return 201 == statusCodeValue; // Modify this based on your API
}

- (BOOL) runSynchronouslyReturningResult:(NSData **) resultPtr error:(NSError **) errorPtr {
    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    NSData *result = [NSURLConnection sendSynchronousRequest:[self request] returningResponse:&response error:&error];
    if (error) {
        if (errorPtr) *errorPtr = error;
        return NO;
    }

    self.statusCode = [response statusCode];
    self.MIMEType = [response MIMEType];
    self.textEncodingName = [response textEncodingName];
    if ([self statusCodeIndicatesSuccess:self.statusCode]) {
        if (resultPtr) *resultPtr = result;
        return YES;
    } else {
        if (errorPtr) *errorPtr = [ServerRequest errorForStatusCode:self.statusCode
                                                        contentType:self.MIMEType
                                                   textEncodingName:self.textEncodingName
                                                               data:result];
        if (resultPtr) *resultPtr = result;
        return NO;
    }
}
于 2012-05-18T16:40:40.237 回答