本文提供一個零依賴、可直接運行的 iOS 網絡請求範例,涵蓋 URL 構建、異步會話、數據解碼、主線程 UI 更新全流程。
// ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - 點擊屏幕發起請求
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"測試");
[self test];
}
- (void)test {
// 1. 統一資源定位符
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
// 2. 創建請求對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 3. 發送異步請求(NSURLSession 默認異步,無同步 API)
// completionHandler 在後台線程執行
[[[NSURLSession sharedSession] dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data,
NSURLResponse * _Nullable response,
NSError * _Nullable error) {
// 4. 二進制數據轉字符串
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// 5. 切回主線程更新 UI
dispatch_async(dispatch_get_main_queue(), ^{
// 6. 創建 WebView 載入 HTML
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
[webView loadHTMLString:html baseURL:url];
[self.view addSubview:webView];
/*
替代方案:
[webView loadData:data MIMEType:nil textEncodingName:nil baseURL:url];
[webView loadRequest:request]; // 直接加載請求
*/
// 7. 可選:保存 HTML 到沙盒
// [data writeToFile:@"路徑/文件.html" atomically:YES];
});
}] resume]; // 必須調用 resume 啟動任務
}
@end
用戶點擊
↓
NSURL (統一資源定位)
↓
NSMutableURLRequest (可變請求,可加 Header/Body)
↓
NSURLSession.sharedSession (單例會話)
↓
dataTaskWithRequest (數據任務)
↓
resume() 啟動
↓
--- 後台線程 ---
completionHandler(data, response, error)
↓
NSData → NSString (UTF-8 解碼)
↓
dispatch_async(main_queue) 切主線程
↓
UIWebView 初始化 + loadHTMLString
↓
addSubview 顯示
網絡 I/O 屬於耗時操作,若在主線程同步阻塞會導致界面卡頓甚至觸發 Watchdog 崩潰(0x8badf00d)。iOS 強制網絡 API 異步化。
resume:立即返回,底層開啟網絡連接completionHandler:**默認在後台串行隊列**執行(非主線程)delegateQueue(默認主隊列)| UIWebView | WKWebView | |
|---|---|---|
| 狀態 | iOS 12 棄用,App Store 可能拒審 | 推薦,持續維護 |
| 進程 | App 進程內(佔用 App 內存) | 獨立進程(內存隔離,崩潰不影響 App) |
| 性能 | 較差 | 接近 Safari,JS 引擎快 |
| API | 簡單 | 功能豐富(導航代理、腳本注入等) |
resume():任務創建後處於掛起狀態,必須調用 resume 才會發送請求。Info.plist 配置 NSAppTransportSecurity 允許 HTTP 或特定域名。dispatch_async(main_queue)。initWithData:encoding: 返回 nil。可嘗試 CFStringConvertEncodingToNSStringEncoding 檢測編碼。error 與 response.statusCoderequest.timeoutInterval = 15;request.cachePolicy = NSURLRequestUseProtocolCachePolicy;downloadTask 支持斷點續傳AFNetworking (OC) / Alamofire (Swift) 封裝更友好