iOS网络编程(六)NSURLSession详解

#import "HMTRootViewController.h"
010. #import "HMTAppDelegate.h"
011.  
012.  
013. @interface HMTRootViewController ()
014.  
015. @property (nonatomic,strong)UIImageView *imageView;
016. @property (nonatomic,strong)UIProgressView *progressIndicator;
017.  
018. @property (nonatomic,strong)NSURLSession *urlSession;         //  普通会话
019. //@property (nonatomic,strong)NSURLSession *backgroundSession;  //  后台会话
020. @property (nonatomic,strong)NSURLSessionDownloadTask *sessionDownloadTask;  //  下载Task
021. @property (nonatomic,strong)NSURLSessionDownloadTask *resumableTask;        //  恢复下载Task
022. @property (nonatomic,strong)NSURLSessionDownloadTask *backgroundTask;       //  后台下载Task
023. @property (nonatomic,strong)NSData *partialData;   //  下载的局部数据
024.  
025. @end
026.  
027. @implementation HMTRootViewController
028.  
029. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
030. {
031. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
032. if (self) {
033. // Custom initialization
034. }
035. return self;
036. }
037.  
038. - (void)viewDidLoad{
039.  
040. [super viewDidLoad];
041.  
042. self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(064320300)];
043. [self.view addSubview:_imageView];
044.  
045. self.progressIndicator = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
046. _progressIndicator.frame = CGRectMake(5050022050);
047. [self.view addSubview:_progressIndicator];
048.  
049. UIButton *cancleButton = [UIButton buttonWithType:UIButtonTypeSystem];
050. cancleButton.frame = CGRectMake(1204004040);
051. [cancleButton setTitle:@"取消" forState:UIControlStateNormal];
052. [cancleButton addTarget:self action:@selector(didClickCancleButtonAction:) forControlEvents:UIControlEventTouchUpInside];
053. [self.view addSubview:cancleButton];
054.  
055. UIButton *downloadButton = [UIButton buttonWithType:UIButtonTypeSystem];
056. downloadButton.frame = CGRectMake(204004040);
057. [downloadButton setTitle:@"下载" forState:UIControlStateNormal];
058. [downloadButton addTarget:self action:@selector(didClickDownloadButtonAction:) forControlEvents:UIControlEventTouchUpInside];
059. [self.view addSubview:downloadButton];
060.  
061. UIButton *uploadButton = [UIButton buttonWithType:UIButtonTypeSystem];
062. uploadButton.frame = CGRectMake(704004040);
063. [uploadButton setTitle:@"上传" forState:UIControlStateNormal];
064. [uploadButton addTarget:self action:@selector(didClickUploadButtonAction:) forControlEvents:UIControlEventTouchUpInside];
065. [self.view addSubview:uploadButton];
066.  
067. UIButton *resumableButton = [UIButton buttonWithType:UIButtonTypeSystem];
068. resumableButton.frame = CGRectMake(1804004040);
069. [resumableButton setTitle:@"恢复" forState:UIControlStateNormal];
070. [resumableButton addTarget:self action:@selector(didClickResuableButtonAction:) forControlEvents:UIControlEventTouchUpInside];
071. [self.view addSubview:resumableButton];
072.  
073. UIButton *backgroundLoadButton = [UIButton buttonWithType:UIButtonTypeSystem];
074. backgroundLoadButton.frame = CGRectMake(2204008040);
075. [backgroundLoadButton setTitle:@"后台下载" forState:UIControlStateNormal];
076. [backgroundLoadButton addTarget:self action:@selector(didClickBackgroundButtonAction:) forControlEvents:UIControlEventTouchUpInside];
077. [self.view addSubview:backgroundLoadButton];
078.  
079.  
080. #pragma mark - 如果我们需要利用NSURLSession进行数据传输我们需要:
081. /**
082. *  创建一个NSURLSessionConfiguration,用于创建NSSession时设置工作模式(3种)
083. *  (1)一般模式(default):工作模式类似于原来的NSURLConnection,可以使用缓存的Cache,Cookie,鉴权。
084. *  (2)及时模式(ephemeral):不使用缓存的Cache,Cookie,鉴权。
085. *  (3)后台模式(background):在后台完成上传下载,创建Configuration对象的时候需要给一个NSString的ID用于追踪完成工作的Session是哪一个
086. */
087. NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
088.  
089. /**
090. *  @网络设置:参考NSURLConnection中的设置项
091. *  两种创建方法(目前不太懂什么区别)
092. *  (1)就是根据刚才创建的Configuration创建一个Session,系统默认创建一个新的OperationQueue处理Session的消息
093. *  (2)可以设定回调的delegate(注意这个回调delegate会被强引用),并且可以设定delegate在哪个OperationQueue回调,如果我们将其
094. *     设置为[NSOperationQueue mainQueue]就能在主线程进行回调非常的方便
095. */
096. //NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
097. self.urlSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]];
098. NSURL *url = [NSURL URLWithString:@"http://www.bizhiwa.com/uploads/allimg/2012-01/22021207-1-311536.jpg"];
099. NSURLRequest *request = [NSURLRequest requestWithURL:url];
100.  
101. /**
102. *  NSURLSessionUploadTask:上传用的Task,传完以后不会再下载返回结果;
103. *  NSURLSessionDownloadTask:下载用的Task;
104. *  NSURLSessionDataTask:可以上传内容,上传完成后再进行下载。
105. */
106. self.sessionDownloadTask = [self.urlSession downloadTaskWithRequest:request];
107.  
108. //  同NSURLConnection一样,有代理方法也就有block方法
109. //    [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
110. //    }];
111.  
112. }
113.  
114. #pragma mark 点击下载
115. - (void)didClickDownloadButtonAction:(UIButton *)button{
116.  
117. // 因为任务默认是挂起状态,需要恢复任务(执行任务)
118. [_sessionDownloadTask resume];
119.  
120. }
121.  
122. #pragma mark 点击上传
123. - (void)didClickUploadButtonAction:(UIButton *)button{
124.  
125. //判断imageView是否有内容
126. if (_imageView.image == nil) {
127.  
128. NSLog(@"image view is empty");
129. return;
130.  
131. }
132.  
133. // 0. 上传之前在界面上添加指示符
134. UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
135. // 设置位置???
136. CGSize size = _imageView.bounds.size;
137. indicator.center = CGPointMake(size.width / 2.0, size.height / 2.0);
138. [self.imageView addSubview:indicator];
139. [indicator startAnimating];
140.  
141. // 1. URL
142. NSURL *url = [NSURL URLWithString:@"http://www.bizhiwa.com/uploads/allimg/2012-01/22021207-1-311536.jpg"];
143.  
144. // 2. Request -> PUT,request的默认操作是GET
145. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0f];
146. request.HTTPMethod = @"PUT";
147.  
148. // *** 设置网络请求的身份验证! ***
149.  
150. // 1> 授权字符串
151.  
152. NSString *authStr = @"admin:123456";
153.  
154. // 2> BASE64的编码,避免数据在网络上以明文传输
155. // iOS中,仅对NSData类型的数据提供了BASE64的编码支持
156. NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
157. NSString *encodeStr = [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];
158. NSString *authValue = [NSString stringWithFormat:@"Basic %@", encodeStr];
159. [request setValue:authValue forHTTPHeaderField:@"Authorization"];
160.  
161. // 3. Session
162. NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
163. NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]];
164.  
165. // 4. UploadTask
166. NSData *imageData = UIImageJPEGRepresentation(_imageView.image, 0.75);
167. //  应用block的请求方式
168. NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:imageData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
169.  
170. // 上传完成后,data参数转换成string就是服务器返回的内容
171.  
172. NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
173. NSLog(@"OK -> %@", str);
174.  
175. [NSThread sleepForTimeInterval:5.0f];
176.  
177. dispatch_async(dispatch_get_main_queue(), ^{
178.  
179. [indicator stopAnimating];
180. [indicator removeFromSuperview];
181.  
182. });
183.  
184. }];
185.  
186. // 因为任务默认是挂起状态,需要恢复任务(执行任务)
187. [uploadTask resume];
188. }
189.  
190. #pragma mark 点击取消
191. //  NSURLConnection一旦发送是没法取消的。但是,我们可以很容易的取消掉一个NSURLSessionTask任务
192. - (void)didClickCancleButtonAction:(UIButton *)button{
193.  
194. /**
195. *  当取消后,会回调这个URLSession:task:didCompleteWithError:代理方法,通知你去及时更新UI。当取消一个任务后,也
196. *  十分可能会再一次回调这个代理方法URLSession:downloadTask:didWriteData:BytesWritten:totalBytesExpectedToWrite:
197. *  当然,didComplete 方法肯定是最后一个回调的。
198. */
199. //    if (_sessionDownloadTask) {
200. //       
201. //        //  取消下载请求
202. //        [_sessionDownloadTask cancel];
203. //        _sessionDownloadTask = nil;
204. //    }
205.  
206. if (!self.sessionDownloadTask) {
207.  
208. //  停止下载任务,把待恢复的数据保存到一个变量中,方便后面恢复下载使用
209. [self.sessionDownloadTask cancelByProducingResumeData:^(NSData *resumeData) {
210.  
211. self.partialData = resumeData;
212. self.sessionDownloadTask = nil;
213.  
214. }];
215. }
216. }
217.  
218. #pragma mark  恢复下载(断点续传)
219. - (void)didClickResuableButtonAction:(UIButton *)button{
220.  
221. if (self.partialData) {
222.  
223. self.sessionDownloadTask = [self.urlSession downloadTaskWithResumeData:self.partialData];
224. self.partialData = nil;
225.  
226. }else{
227.  
228. NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://pic4.duowan.com/wow/1002/130782267821/130782458426.jpg"]];
229. self.resumableTask = [self.urlSession downloadTaskWithRequest:request];
230.  
231. }
232.  
233. [self.sessionDownloadTask resume];
234.  
235. }
236.  
237. #pragma mark 后台下载模式
238. - (void)didClickBackgroundButtonAction:(UIButton *)button{
239.  
240. NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://dldir1.<;a href="http://www.it165.net/qq/" target="_blank" class="keylink">qq</a>.com/<a href="http://www.it165.net/qq/" target="_blank" class="keylink">qq</a>file/QQforMac/QQ_V3.1.2.dmg"]];
241. self.backgroundTask = [[self backgroundSession] downloadTaskWithRequest:request];
242.  
243. [self.backgroundTask resume];
244. }
245.  
246. #pragma mark - NSURLSessionDownloadTaskDelegate
247. //  下载完成
248. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
249.  
250. /**
251. *******->appDelegete里面的方法
252. typedef void(^MyBlock)();
253. @property (copy, nonatomic) MyBlock backgroundURLSessionCompletionHandler;
254. //  后台请求结束时调用的方法
255. - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
256.  
257. self.backgroundURLSessionCompletionHandler = completionHandler;
258. }
259.  
260. */
261. //  如果是后台NSURLSession,后台请求结束后会调用这个方法,通知你应该更新UI了
262. if (session == [self backgroundSession]) {
263.  
264. self.backgroundTask = nil;
265. HMTAppDelegate *appDelegate = (HMTAppDelegate *)[UIApplication sharedApplication].delegate;
266. if (appDelegate.backgroundURLSessionCompletionHandler) {
267.  
268. void(^handler)() = appDelegate.backgroundURLSessionCompletionHandler;
269. appDelegate.backgroundURLSessionCompletionHandler = nil;
270. handler();
271. }
272.  
273. }
274.  
275. //  这里的缓存处理做的不好,大家按自己的方法处理就行,还有图片的存储以它本身的URL路径为准,这样是不会有重复的
276. NSFileManager *fileManager = [NSFileManager defaultManager];
277. NSURL *cachesURLPath = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
278. //  根据URL获取到下载的文件名,拼接成沙盒的存储路径(location是下载的临时文件目录,在tmp文件夹里面)
279. NSURL *destinationPath = [cachesURLPath URLByAppendingPathComponent:[location lastPathComponent]];
280.  
281. NSError *error = nil;
282. BOOL success = [fileManager moveItemAtURL:location toURL:destinationPath error:&error];
283. [fileManager removeItemAtURL:location error:NULL];
284.  
285. //  location是下载的临时文件目录,将文件从临时文件夹复制到沙盒
286. //    BOOL success = [fileManager copyItemAtURL:location toURL:destinationPath error:&error];
287. if (success) {
288.  
289. dispatch_async(dispatch_get_main_queue(), ^{
290.  
291. UIImage *image = [UIImage imageWithContentsOfFile:[destinationPath path]];
292. self.imageView.image = image;
293. //  UIImageView会自动裁剪图片适应它的frame,下面这个属性就是展示原图
294. self.imageView.contentMode = UIViewContentModeScaleAspectFill;
295.  
296. });
297. }
298.  
299. }
300.  
301. //  不管任务是否成功,在完成后都会回调这个代理方法
302. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
303.  
304. //  如果error是nil,则证明下载是成功的,否则就要通过它来查询失败的原因。如果下载了一部分,这个error会包含一个NSData对象,如果后面要恢复任务可以用到
305. if (error == nil) {
306.  
307. dispatch_async(dispatch_get_main_queue(), ^{
308.  
309. self.progressIndicator.hidden = YES;
310. });
311. }
312.  
313. }
314.  
315. //  传输进度
316. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
317.  
318. double currentValue = totalBytesWritten / (double)totalBytesExpectedToWrite;
319. dispatch_async(dispatch_get_main_queue(), ^{
320. NSLog(@"%f",currentValue);
321. self.progressIndicator.hidden = NO;
322. self.progressIndicator.progress = currentValue;
323. });
324. }
325.  
326. //  未知
327. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
328.  
329. }
330.  
331. #pragma mark - NSURLSession另一个重要的特性:即使当应用不在前台时,你也可以继续传输任务。当然,我们的会话模式也要为后台模式
332. - (NSURLSession *)backgroundSession{
333.  
334. //  通过给的后台token,我们只能创建一个后台会话,所以这里使用dispatch once block
335. static NSURLSession *backgroundSession = nil;
336. static dispatch_once_t onceToken;
337. dispatch_once(&onceToken, ^{
338.  
339. NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.shinobicontrols.BackgroundDownload.BackgroundSession"];
340. backgroundSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
341.  
342. });
343.  
344. return backgroundSession;
345. }
346.  
347. - (void)didReceiveMemoryWarning
348. {
349. [super didReceiveMemoryWarning];
350. // Dispose of any resources that can be recreated.
351. }
352.  
353. /*
354. #pragma mark - Navigation
355.  
356. // In a storyboard-based application, you will often want to do a little preparation before navigation
357. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
358. {
359. // Get the new view controller using [segue destinationViewController].
360. // Pass the selected object to the new view controller.
361. }
362. */
363.  
364. @end

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值