You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS API调用偶现'data parameter is nil'异常求助

Hey Renee, let's break down your problem step by step—you're hitting two main issues here: the TCP error code 53 that pops up when returning from the background, and the fatal crash caused by trying to parse nil data. Let's fix them one by one:

First, Stop the Immediate Crash

The crash happens because you’re calling NSJSONSerialization JSONObjectWithData:data without checking if data is nil or if an error occurred. When the TCP connection fails (error 53), the data parameter will be nil, and trying to parse it throws that NSInvalidArgumentException.

Add a guard check right at the start of your completion handler to handle this:

[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler: ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    // First handle errors and nil data
    if (error != nil || data == nil) {
        NSLog(@"API Request Failed: %@", error?.localizedDescription ?: @"No data received");
        dispatch_async(dispatch_get_main_queue(), ^{
            [self->HUD hide:YES];
            // Optionally show an alert to the user about the network issue
        });
        return;
    }

    // Now proceed with JSON parsing, and check for parsing errors too
    NSError *jsonError = nil;
    NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
    
    if (jsonError != nil) {
        NSLog(@"JSON Parsing Failed: %@", jsonError.localizedDescription);
        dispatch_async(dispatch_get_main_queue(), ^{
            [self->HUD hide:YES];
        });
        return;
    }

    // Rest of your parsing logic for arrList, arrActive, etc.
}] resume];

Fix the TCP Error 53 (Connection Failure on Background → Foreground Switch)

Error code 53 in iOS usually means the TCP connection was reset—this often happens when your app is in the background and the system drops idle connections, or the network state changed (like switching from Wi-Fi to cellular).

Here’s how to mitigate this:

  • Check network state first: Use NWPathMonitor (from the Network framework) to verify if the device has an active network connection before firing the API call. This prevents trying to make requests when there’s no network.
  • Implement retry logic: When you get error 53, add a limited retry mechanism (2-3 retries max) to reattempt the request.
  • Use a custom URLSession: The shared NSURLSession has default settings that don’t handle background transitions well. Create a custom session with waitsForConnectivity = YES to let it wait for a network connection instead of failing immediately:
    NSURLSessionConfiguration *config = NSURLSessionConfiguration.defaultConfiguration;
    config.waitsForConnectivity = YES;
    NSURLSession *customSession = [NSURLSession sessionWithConfiguration:config];
    // Use customSession for your data tasks instead of sharedSession
    

Fix the URL Formatting Bug (Critical!)

Looking at your code, there’s a major issue with how you’re building targetUrl:

targetUrl = [NSString stringWithFormat:@"https://yoururl",[dict valueForKey:@"support_location"],@"1000"];

You’re using stringWithFormat but your format string has no placeholders (%@) for the two parameters you’re passing. This means your URL is just https://yoururl (likely invalid) instead of including the support_location and limit. Fix this by adding the missing placeholders:

// Adjust the format to match your actual API endpoint structure
targetUrl = [NSString stringWithFormat:@"https://yoururl/%@?limit=%@",[dict valueForKey:@"support_location"],@"1000"];

This is probably a key reason some requests fail—invalid URLs will trigger connection errors.

Other Code Improvements

  • Avoid self-> for instance variables: Use property accessors (like self.arrList instead of self->arrList) to ensure proper memory management and KVO compliance.
  • Null-check dictionary values: When accessing keys like user_id, verify the value isn’t nil before converting to an integer (e.g., [dict valueForKey:@"user_id"] ?: @0).
  • Reuse your URLSession: Create your custom session once (in viewDidLoad or init) instead of recreating it every time you make a request.

With these changes, your API calls will handle network failures gracefully, avoid crashes, and be much more stable—especially when switching between background and foreground.

内容的提问来源于stack exchange,提问作者Renee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:50:16