Skip to content

Commit e54aab8

Browse files
committed
NSURLSession分析
1 parent 0983171 commit e54aab8

6 files changed

Lines changed: 926 additions & 14 deletions

File tree

AFNetWorking3.X源码阅读/AFNetWorking3.X源码阅读.xcodeproj/xcuserdata/huangchengdu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

Lines changed: 678 additions & 7 deletions
Large diffs are not rendered by default.
Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,91 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1004" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="FI6-ak-q2L">
3+
<device id="retina4_7" orientation="portrait">
4+
<adaptation id="fullscreen"/>
5+
</device>
36
<dependencies>
4-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
7+
<deployment identifier="iOS"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
59
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
610
</dependencies>
711
<scenes>
812
<!--View Controller-->
913
<scene sceneID="tne-QT-ifu">
1014
<objects>
11-
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
15+
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
1216
<layoutGuides>
1317
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
1418
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
1519
</layoutGuides>
1620
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
1721
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
1822
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
23+
<subviews>
24+
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="weo-ai-Pd7">
25+
<rect key="frame" x="0.0" y="351" width="375" height="316"/>
26+
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
27+
<constraints>
28+
<constraint firstAttribute="height" constant="316" id="Qzx-NV-Ueg"/>
29+
</constraints>
30+
</imageView>
31+
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GoY-Dl-62s">
32+
<rect key="frame" x="138" y="152" width="99" height="30"/>
33+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
34+
<state key="normal" title="downloadTask"/>
35+
<connections>
36+
<action selector="requestDownloadTest:" destination="BYZ-38-t0r" eventType="touchUpInside" id="45Q-mc-fBi"/>
37+
</connections>
38+
</button>
39+
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eyc-sa-Zab">
40+
<rect key="frame" x="153" y="206" width="69" height="30"/>
41+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
42+
<state key="normal" title="blockTask"/>
43+
<connections>
44+
<action selector="requestBlockTaskTest:" destination="BYZ-38-t0r" eventType="touchUpInside" id="hdD-eT-64I"/>
45+
</connections>
46+
</button>
47+
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZuX-WW-stN">
48+
<rect key="frame" x="128" y="106" width="119" height="30"/>
49+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
50+
<state key="normal" title="dataTask"/>
51+
<connections>
52+
<action selector="requestDataTest:" destination="BYZ-38-t0r" eventType="touchUpInside" id="DHD-cD-yHG"/>
53+
</connections>
54+
</button>
55+
</subviews>
1956
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
57+
<constraints>
58+
<constraint firstItem="weo-ai-Pd7" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="QrF-jP-9bX"/>
59+
<constraint firstAttribute="trailing" secondItem="weo-ai-Pd7" secondAttribute="trailing" id="XLf-a1-ph7"/>
60+
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="weo-ai-Pd7" secondAttribute="bottom" id="ueW-FQ-WCu"/>
61+
</constraints>
2062
</view>
63+
<navigationItem key="navigationItem" id="RSe-lC-kxs"/>
64+
<connections>
65+
<outlet property="imageView" destination="weo-ai-Pd7" id="xZI-7n-QIc"/>
66+
</connections>
2167
</viewController>
2268
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
2369
</objects>
70+
<point key="canvasLocation" x="1260" y="9.4452773613193415"/>
71+
</scene>
72+
<!--Navigation Controller-->
73+
<scene sceneID="3Uh-Ya-kId">
74+
<objects>
75+
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="FI6-ak-q2L" sceneMemberID="viewController">
76+
<toolbarItems/>
77+
<navigationBar key="navigationBar" contentMode="scaleToFill" id="oxF-Yi-Vx4">
78+
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
79+
<autoresizingMask key="autoresizingMask"/>
80+
</navigationBar>
81+
<nil name="viewControllers"/>
82+
<connections>
83+
<segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="Xzm-xd-avE"/>
84+
</connections>
85+
</navigationController>
86+
<placeholder placeholderIdentifier="IBFirstResponder" id="80G-TE-YZR" userLabel="First Responder" sceneMemberID="firstResponder"/>
87+
</objects>
88+
<point key="canvasLocation" x="140" y="138.98050974512745"/>
2489
</scene>
2590
</scenes>
2691
</document>

AFNetWorking3.X源码阅读/AFNetWorking3.X源码阅读/Info.plist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,10 @@
4141
<string>UIInterfaceOrientationLandscapeLeft</string>
4242
<string>UIInterfaceOrientationLandscapeRight</string>
4343
</array>
44+
<key>NSAppTransportSecurity</key>
45+
<dict>
46+
<key>NSAllowsArbitraryLoads</key>
47+
<true/>
48+
</dict>
4449
</dict>
4550
</plist>

AFNetWorking3.X源码阅读/AFNetWorking3.X源码阅读/ViewController.m

Lines changed: 175 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,193 @@
88

99
#import "ViewController.h"
1010

11-
@interface ViewController ()
11+
static NSString *const bigPic = @"http://i1.piimg.com/4851/d1498fea89ae3bc1.png";
12+
static NSString *const smallPic = @"http://i1.piimg.com/4851/97aef4680d359905.png";
1213

14+
@interface ViewController ()<NSURLSessionDelegate>
15+
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
16+
@property(nonatomic,strong)NSMutableData *data;
1317
@end
1418

1519
@implementation ViewController
1620

1721
- (void)viewDidLoad {
1822
[super viewDidLoad];
23+
1924
// Do any additional setup after loading the view, typically from a nib.
2025
}
2126

27+
- (IBAction)requestDataTest:(id)sender {
28+
[self clear];
29+
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
30+
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
31+
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
32+
[dataTask resume];
33+
}
34+
2235

23-
- (void)didReceiveMemoryWarning {
24-
[super didReceiveMemoryWarning];
25-
// Dispose of any resources that can be recreated.
36+
- (IBAction)requestDownloadTest:(id)sender {
37+
[self clear];
38+
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
39+
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
40+
NSURLSessionDownloadTask *dataTask = [session downloadTaskWithRequest:request];
41+
[dataTask resume];
2642
}
2743

44+
-(IBAction)requestBlockTaskTest:(id)sender{
45+
[self clear];
46+
NSURLSession *session = [NSURLSession sharedSession];
47+
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:bigPic]];
48+
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
49+
UIImage *image = [[UIImage alloc]initWithData:data];
50+
self.imageView.image = image;
51+
}];
52+
[dataTask resume];
53+
}
54+
55+
-(void)clear{
56+
self.imageView.image = nil;
57+
}
58+
59+
//==============================NSURLSessionDelegate========================
60+
#pragma NSURLSessionDelegate
61+
//当一个session遇到系统错误或者未检测到的错误的时候,就会调用这个方法。
62+
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error{
63+
64+
}
65+
//当请求需要认证、或者https证书认证的时候,我们就需要在这个方法里面处理。
66+
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
67+
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
68+
69+
}
70+
//如果应用进入后台、这个方法会被调用。我们在这里可以对session发起的请求做各种操作比如请求完成的回调等。
71+
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
2872

73+
}
74+
75+
//==================================NSURLSessionTaskDelegate====================
76+
#pragma NSURLSessionTaskDelegate
77+
/*
78+
当请求重定向的时候调用这个方法。我们必须设置一个新的`NSURLRequest`对象传入completionHandler来重定向新的请求,但是当`session`是background模式的时候,这个方法不会被调用。
79+
*/
80+
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
81+
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
82+
newRequest:(NSURLRequest *)request
83+
completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler{
84+
85+
}
86+
/*
87+
当请求需要认证的时候调用这个方法。如果没有实现这个代理,那么请求认证这个过程不会被调用。
88+
*/
89+
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
90+
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
91+
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
92+
93+
}
94+
/*
95+
如果请求需要一个新的请求体时,这个方法就会被调用。比如认证失败的时候,我们可以通过这个机会从新认证。
96+
*/
97+
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
98+
needNewBodyStream:(void (^)(NSInputStream * _Nullable bodyStream))completionHandler{
99+
100+
}
101+
/*
102+
当我们上传数据的时候,我们可以通过这个代理方法获取上传进度。
103+
*/
104+
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
105+
didSendBodyData:(int64_t)bytesSent
106+
totalBytesSent:(int64_t)totalBytesSent
107+
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{
108+
NSLog(@"");
109+
}
110+
/*
111+
当task的统计信息收集好了以后,调用这个方法。
112+
*/
113+
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics {
114+
115+
}
116+
/*
117+
当一个task出错的时候,会调用这个方法。如果error是nil,也会调用这个方法,表示task完成。
118+
*/
119+
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
120+
didCompleteWithError:(nullable NSError *)error{
121+
NSLog(@"数据返回以后,不管有错没错都回调用,如果没错,error及时nil");
122+
if (self.data) {
123+
self.imageView.image = [UIImage imageWithData:self.data];
124+
self.data = nil;
125+
}
126+
}
127+
128+
//==================================NSURLSessionDataDelegate=====================================
129+
#pragma NSURLSessionDataDelegate
130+
/*
131+
当一个task接收到返回信息。当所有信息都接收完毕以后,completionHandler会被调用。我们可以在这里取消一个网络请求或者把一个datatask转换为downloadtask。如果没有实现这个代理方法,我们也可以通过task的response属性获取到对应的数据。background模式的uploadtask不会调用这个方法。
132+
*/
133+
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
134+
didReceiveResponse:(NSURLResponse *)response
135+
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler{
136+
self.data = nil;
137+
self.data = [NSMutableData data];
138+
// 允许处理服务器的响应,才会继续接收服务器返回的数据
139+
completionHandler(NSURLSessionResponseAllow);
140+
}
141+
/*
142+
当一个datatask转换为一个downloadtask以后会调用。
143+
*/
144+
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
145+
didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask{
146+
147+
}
148+
/*
149+
暂时忽略,这个是和数据流相关的。不管了
150+
*/
151+
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
152+
didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask{
153+
154+
}
155+
/*
156+
当data可以使用的时候,调用这个方法。我们可以在这里获取data。
157+
*/
158+
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
159+
didReceiveData:(NSData *)data{
160+
[self.data appendData:data];
161+
NSLog(@"具体数据在URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidCompleteWithError:(nullable NSError *)error处理");
162+
}
163+
/*
164+
允许我们在这里调用completionHandler缓存data,或者传入nil来禁止缓存
165+
*/
166+
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
167+
willCacheResponse:(NSCachedURLResponse *)proposedResponse
168+
completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler{
169+
170+
}
171+
//==================================NSURLSessionDownloadTask=================================
172+
#pragma NSURLSessionDownloadTask
173+
/*
174+
当一个下载task任务完成以后,这个方法会被调用。我们可以在这里移动或者复制download的数据
175+
*/
176+
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
177+
didFinishDownloadingToURL:(NSURL *)location{
178+
NSString *path = location.absoluteString;
179+
UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:location]];
180+
self.imageView.image = image;
181+
NSLog(@"数据下载完成以后,会保存在一个location的地方。%@",location);
182+
}
183+
/*
184+
获取下载进度
185+
*/
186+
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
187+
didWriteData:(int64_t)bytesWritten
188+
totalBytesWritten:(int64_t)totalBytesWritten
189+
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
190+
NSLog(@"总得数据大小%lld----",bytesWritten);
191+
}
192+
/*
193+
重启一个下载任务(比如下载一半后停止然后过一点时间继续)。如果下载出错,`NSURLSessionDownloadTaskResumeData`里面包含重新开始下载的数据。
194+
*/
195+
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
196+
didResumeAtOffset:(int64_t)fileOffset
197+
expectedTotalBytes:(int64_t)expectedTotalBytes{
198+
199+
}
29200
@end

0 commit comments

Comments
 (0)