1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//
// VIResourceLoadingRequestWorker.m
// VIMediaCacheDemo
//
// Created by Vito on 4/21/16.
// Copyright © 2016 Vito. All rights reserved.
//
#import "VIResourceLoadingRequestWorker.h"
#import "VIMediaDownloader.h"
#import "VIContentInfo.h"
@import MobileCoreServices;
@import AVFoundation;
@import UIKit;
@interface VIResourceLoadingRequestWorker () <MediaDownloaderDelegate>
@property (nonatomic, strong, readwrite) AVAssetResourceLoadingRequest *request;
@property (nonatomic, strong) VIMediaDownloader *mediaDownloader;
@end
@implementation VIResourceLoadingRequestWorker
- (instancetype)initWithMediaDownloader:(VIMediaDownloader *)mediaDownloader resourceLoadingRequest:(AVAssetResourceLoadingRequest *)request {
self = [super init];
if (self) {
_mediaDownloader = mediaDownloader;
_mediaDownloader.delegate = self;
_request = request;
[self fullfillContentInfo];
}
return self;
}
- (void)startWork {
AVAssetResourceLoadingDataRequest *dataRequest = self.request.dataRequest;
long long offset = dataRequest.requestedOffset;
NSInteger length = dataRequest.requestedLength;
if (dataRequest.currentOffset != 0) {
offset = dataRequest.currentOffset;
}
BOOL toEnd = NO;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
if (dataRequest.requestsAllDataToEndOfResource) {
toEnd = YES;
}
}
[self.mediaDownloader downloadTaskFromOffset:offset length:length toEnd:toEnd];
}
- (void)cancel {
[self.mediaDownloader cancel];
}
- (void)finish {
if (!self.request.isFinished) {
[self.request finishLoadingWithError:[self loaderCancelledError]];
}
}
- (NSError *)loaderCancelledError{
NSError *error = [[NSError alloc] initWithDomain:@"com.resourceloader"
code:-3
userInfo:@{NSLocalizedDescriptionKey:@"Resource loader cancelled"}];
return error;
}
- (void)fullfillContentInfo {
AVAssetResourceLoadingContentInformationRequest *contentInformationRequest = self.request.contentInformationRequest;
if (self.mediaDownloader.info && !contentInformationRequest.contentType) {
// Fullfill content information
contentInformationRequest.contentType = self.mediaDownloader.info.contentType;
contentInformationRequest.contentLength = self.mediaDownloader.info.contentLength;
contentInformationRequest.byteRangeAccessSupported = self.mediaDownloader.info.byteRangeAccessSupported;
}
}
#pragma mark - MediaDownloaderDelegate
- (void)mediaDownloader:(VIMediaDownloader *)downloader didReceiveResponse:(NSURLResponse *)response {
[self fullfillContentInfo];
}
- (void)mediaDownloader:(VIMediaDownloader *)downloader didReceiveData:(NSData *)data {
[self.request.dataRequest respondWithData:data];
}
- (void)mediaDownloader:(VIMediaDownloader *)downloader didFinishedWithError:(NSError *)error {
if (error.code == NSURLErrorCancelled) {
return;
}
if (!error) {
[self.request finishLoading];
} else {
[self.request finishLoadingWithError:error];
}
[self.delegate resourceLoadingRequestWorker:self didCompleteWithError:error];
}
@end