MST

星途 面试题库

面试题:Objective-C中如何在后台任务中处理网络请求

在Objective-C开发中,假设你需要在后台执行一个网络请求任务,描述实现这个功能的主要步骤以及涉及到的关键类和方法。同时说明如何处理网络请求成功或失败的回调,并且要考虑到后台任务可能被系统终止的情况。
20.3万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

主要步骤

  1. 创建网络请求对象:构建要发送的网络请求,包括URL、请求方法(GET、POST等)、请求头和请求体。
  2. 配置后台任务:确保任务在后台执行,而不影响主线程。
  3. 发送网络请求:启动请求并等待响应。
  4. 处理响应:根据请求的成功或失败,执行相应的回调逻辑。
  5. 处理后台任务终止:保存必要的状态信息,以便在应用重新启动时可以恢复任务。

关键类和方法

  1. NSURLSession:用于创建网络请求会话,管理网络请求任务。
    • 类方法+sharedSession 创建一个共享的会话对象,适用于大多数应用场景;+sessionWithConfiguration:delegate:delegateQueue: 创建一个自定义配置的会话对象,可指定代理和代理队列。
    • 实例方法-dataTaskWithURL:completionHandler: 创建一个数据任务,用于获取服务器返回的数据,完成后通过完成处理程序回调;-uploadTaskWithRequest:fromData:completionHandler: 创建一个上传任务,用于向服务器上传数据,完成后通过完成处理程序回调。
  2. NSURLRequest:表示一个网络请求,包含请求的URL、请求方法、请求头和请求体等信息。
    • 初始化方法-initWithURL: 使用给定的URL初始化一个请求;-initWithURL:cachePolicy:timeoutInterval: 可以同时指定缓存策略和超时时间。
  3. NSURLSessionDataTask:NSURLSession创建的任务之一,用于处理HTTP请求并获取数据响应。
    • 实例方法-resume 启动任务,开始发送请求。

处理网络请求成功或失败的回调

  1. 使用完成处理程序
    NSURLSession *session = [NSURLSession sharedSession];
    NSURL *url = [NSURL URLWithString:@"https://example.com/api"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (!error) {
            // 请求成功
            // 处理返回的数据
            NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"成功: %@", responseString);
        } else {
            // 请求失败
            NSLog(@"失败: %@", error.localizedDescription);
        }
    }];
    [task resume];
    
  2. 使用代理方法
    • 首先创建一个遵守 NSURLSessionDataDelegate 协议的类。
    @interface MySessionDelegate : NSObject <NSURLSessionDataDelegate>
    @end
    
    @implementation MySessionDelegate
    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
        // 可以逐步处理接收到的数据
    }
    
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
        if (!error) {
            // 请求成功
            NSLog(@"成功");
        } else {
            // 请求失败
            NSLog(@"失败: %@", error.localizedDescription);
        }
    }
    @end
    
    • 然后使用自定义配置创建会话并设置代理。
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    MySessionDelegate *delegate = [[MySessionDelegate alloc] init];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:delegate delegateQueue:nil];
    NSURL *url = [NSURL URLWithString:@"https://example.com/api"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
    [task resume];
    

处理后台任务可能被系统终止的情况

  1. 使用NSURLSession的后台配置
    • 创建一个后台配置的 NSURLSessionConfiguration
    NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.backgroundSession"];
    
    • 使用该配置创建 NSURLSession
    NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:nil];
    
  2. 保存任务状态:在任务执行过程中,定期保存任务的进度和状态信息到持久化存储(如 NSUserDefaults、文件系统等)。
  3. 应用启动时恢复任务:在应用启动时,检查保存的任务状态信息,重新创建并恢复被终止的任务。
    • AppDelegateapplication:didFinishLaunchingWithOptions: 方法中:
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.backgroundSession"];
        self.backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:nil];
    
        // 检查是否有需要恢复的任务
        if (launchOptions[UIApplicationLaunchOptionsURLKey]) {
            NSArray *pendingTasks = [self.backgroundSession tasksWithCompletionHandler:^(NSArray<NSURLSessionTask *> * _Nonnull tasks) {
                for (NSURLSessionTask *task in tasks) {
                    [task resume];
                }
            }];
        }
    
        return YES;
    }
    
  4. 实现代理方法处理任务恢复:实现 NSURLSession 的代理方法,如 URLSession:task:didCompleteWithError:,在任务完成或失败时更新任务状态并处理可能的恢复逻辑。
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
        if (error) {
            // 处理失败,记录错误信息
        } else {
            // 处理成功,更新任务状态为已完成
        }
        // 检查是否需要重新启动任务
        if (/* 满足重新启动条件 */) {
            // 重新创建并启动任务
        }
    }