├── .DS_Store ├── .gitignore ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md ├── SPGlobalFile ├── SPGlobalConst.h ├── SPGlobalConst.m └── SPPrefixHeader.pch ├── SPTool ├── SPSingleton.h ├── SPUploadManager.h └── SPUploadManager.m ├── SPUpload ├── Controller │ ├── SPDocUpListVC.h │ └── SPDocUpListVC.m ├── Model │ ├── SPDocUploadModel.h │ └── SPDocUploadModel.m └── View │ ├── SPDocUploadCell.h │ └── SPDocUploadCell.m ├── SPUploadDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── SPUploadDemo.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── SPUploadDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── document.imageset │ │ ├── Contents.json │ │ └── document-2.png │ └── video.imageset │ │ ├── Contents.json │ │ └── video-2.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m └── demo.PNG /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superxjhw/SPUploadTool/165757dc2d277ff72f18c86d891fbfff68df73de/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | Pods/ 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata/ 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xccheckout 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | *.dSYM.zip 30 | *.dSYM 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | # Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | # fastlane 48 | # 49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 50 | # screenshots whenever they are needed. 51 | # For more information about the recommended setup visit: 52 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 53 | 54 | fastlane/report.xml 55 | fastlane/Preview.html 56 | fastlane/screenshots 57 | fastlane/test_output 58 | 59 | # Code Injection 60 | # 61 | # After new code Injection tools there's a generated folder /iOSInjectionProject 62 | # https://github.com/johnno1962/injectionforxcode 63 | 64 | iOSInjectionProject/ 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Super 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '8.0' 3 | pod 'AFNetworking', '~> 3.1.0' 4 | pod 'Masonry', '~> 1.1.0' 5 | pod 'MJExtension', '~> 3.0.13' 6 | target 'SPUploadDemo' do 7 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks 8 | # use_frameworks! 9 | 10 | # Pods for SPUploadDemo 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (3.1.0): 3 | - AFNetworking/NSURLSession (= 3.1.0) 4 | - AFNetworking/Reachability (= 3.1.0) 5 | - AFNetworking/Security (= 3.1.0) 6 | - AFNetworking/Serialization (= 3.1.0) 7 | - AFNetworking/UIKit (= 3.1.0) 8 | - AFNetworking/NSURLSession (3.1.0): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (3.1.0) 13 | - AFNetworking/Security (3.1.0) 14 | - AFNetworking/Serialization (3.1.0) 15 | - AFNetworking/UIKit (3.1.0): 16 | - AFNetworking/NSURLSession 17 | - Masonry (1.1.0) 18 | - MJExtension (3.0.15.1) 19 | 20 | DEPENDENCIES: 21 | - AFNetworking (~> 3.1.0) 22 | - Masonry (~> 1.1.0) 23 | - MJExtension (~> 3.0.13) 24 | 25 | SPEC REPOS: 26 | https://github.com/cocoapods/specs.git: 27 | - AFNetworking 28 | - Masonry 29 | - MJExtension 30 | 31 | SPEC CHECKSUMS: 32 | AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67 33 | Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 34 | MJExtension: 19bc33ce2eee2d319760f5622562cf581a6ff756 35 | 36 | PODFILE CHECKSUM: ea57164c1a4cacbafcf4d2fefb5450e26b515009 37 | 38 | COCOAPODS: 1.5.3 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SPUploadTool 2 | iOS通过切片仿断点机制上传文件 3 | ```objc 4 |    // 这里需要配置上传的接口 相关参数自己修改 请使用真机测试 5 | NSString *const kSuperUploadTestUrl = @"http://www.cnblogs.com/chao8888/p/8058457.html"; 6 | ``` 7 | ![效果图](./demo.PNG) 8 | -------------------------------------------------------------------------------- /SPGlobalFile/SPGlobalConst.h: -------------------------------------------------------------------------------- 1 | // SPGlobalConst.h 2 | // 3 | // Created by SPSuper on 2017/3/9. 4 | 5 | #import 6 | 7 | extern NSString *const kSuperUploadFile; 8 | extern NSString *const kSuperFinishedUpload; 9 | 10 | extern NSString *const kSuperUploadTestUrl; 11 | 12 | // 断点上传切片大小 13 | extern NSInteger const kSuperUploadBlockSize; 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /SPGlobalFile/SPGlobalConst.m: -------------------------------------------------------------------------------- 1 | // SPGlobalConst.h 2 | // 3 | // Created by SPSuper on 2017/3/9. 4 | 5 | 6 | NSString *const kSuperUploadFile = @"kSuperUploadFile"; 7 | NSString *const kSuperFinishedUpload = @"kSuperFinishedUpload"; 8 | 9 | // 测试URL 需要自己配置 10 | NSString *const kSuperUploadTestUrl = @"http://120.24.39.25/api/nzp-core-openapi-server/rest/files/MTBPUpload"; 11 | 12 | // 1M 13 | NSInteger const kSuperUploadBlockSize = 1 * 1024 * 1024; 14 | 15 | 16 | -------------------------------------------------------------------------------- /SPGlobalFile/SPPrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // SPPrefixHeader.pch 3 | // SPUploadDemo 4 | // 5 | // Created by SPSuper on 2017/12/25. 6 | // Copyright © 2017年 SPSuper. All rights reserved. 7 | // 8 | 9 | #ifndef SPPrefixHeader_pch 10 | #define SPPrefixHeader_pch 11 | 12 | #import 13 | #import 14 | #import 15 | 16 | 17 | #import "SPSingleton.h" 18 | #import "SPGlobalConst.h" 19 | #import "SPUploadManager.h" 20 | 21 | // Include any system framework and library headers here that should be included in all compilation units. 22 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 23 | 24 | #endif /* SPPrefixHeader_pch */ 25 | -------------------------------------------------------------------------------- /SPTool/SPSingleton.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPSingleton.h 3 | // 4 | // 5 | // Created by SPSuper on 2016/12/2. 6 | // 单例模式设计 by Super 7 | 8 | #define SingletonH(name) + (instancetype)share##name; 9 | 10 | // ARC 11 | #if __has_feature(objc_arc) 12 | #define SingletonM(name) static id _instance;\ 13 | + (instancetype)allocWithZone:(struct _NSZone *)zone {\ 14 | static dispatch_once_t onceToken;\ 15 | dispatch_once(&onceToken, ^{\ 16 | _instance = [super allocWithZone:zone];\ 17 | });\ 18 | return _instance;}\ 19 | + (instancetype)share##name { return [[self alloc] init]; }\ 20 | - (id)copyWithZone:(NSZone *)zone { return _instance; }\ 21 | - (id)mutableCopyWithZone:(NSZone *)zone { return _instance; } 22 | 23 | // MRC 24 | #else 25 | #define SingletonM(name) static id _instance;\ 26 | + (instancetype)allocWithZone:(struct _NSZone *)zone {\ 27 | static dispatch_once_t onceToken;\ 28 | dispatch_once(&onceToken, ^{\ 29 | _instance = [super allocWithZone:zone];\ 30 | });\ 31 | return _instance;}\ 32 | + (instancetype)share##name { return [[self alloc] init]; }\ 33 | - (id)copyWithZone:(NSZone *)zone { return _instance; }\ 34 | - (id)mutableCopyWithZone:(NSZone *)zone { return _instance; }\ 35 | - (instancetype)retain { return _instance; }\ 36 | - (oneway void)release { }\ 37 | - (NSUInteger)retainCount { return MAXFLOAT; } 38 | #endif 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /SPTool/SPUploadManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUploadManager.h 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SPDocUploadModel; 12 | @interface SPUploadManager : NSObject 13 | SingletonH(UploadManager); 14 | 15 | @property (nonatomic, strong) NSMutableArray *modelArray; 16 | 17 | - (void)refreshCaches; 18 | 19 | - (void)cancelAllUploadOperations; 20 | 21 | /** 22 | 支持断点续传,上传初始化 23 | 直接传data类型,自动缓存到本地,上传完毕自动清理 24 | @param data 要上传的数据 25 | @param model 需要保存的内容 26 | */ 27 | - (void)uploadData:(NSData *)data withModel:(SPDocUploadModel *)model completion:(void(^)(void))completion; 28 | 29 | /** 30 | 支持断点续传,上传初始化 31 | 直接传data类型,自动缓存到本地,上传完毕自动清理 32 | @param mediaUrl 要上传的文件URL 33 | @param model 需要保存的内容 34 | */ 35 | - (void)uploadUrl:(NSURL *)mediaUrl withModel:(SPDocUploadModel *)model completion:(void(^)(void))completion; 36 | 37 | /** 38 | 续传 39 | @param model 保存的数据模型 40 | */ 41 | - (void)continueUploadWithModel:(SPDocUploadModel *)model; 42 | 43 | 44 | /** 45 | 清理所有上传文件缓存 46 | */ 47 | - (void)clean; 48 | 49 | /** 50 | 移除某一个文件,对应上传列表手动左滑删除以及上传成功后自动删除 51 | */ 52 | - (void)removeUploadModel:(SPDocUploadModel *)model; 53 | 54 | /** 55 | 清理所有上传文件 56 | */ 57 | - (void)removeAll; 58 | 59 | /** 60 | 清理指定文件缓存 61 | 62 | @param filePath 文件路径 63 | */ 64 | - (void)cleanPath:(NSString *)filePath; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /SPTool/SPUploadManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPUploadManager.m 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import "SPUploadManager.h" 10 | #import "SPDocUploadModel.h" 11 | 12 | @implementation SPUploadManager 13 | SingletonM(UploadManager); 14 | 15 | static NSString *uploadListName = @"uploadList"; 16 | 17 | - (NSMutableArray *)modelArray { 18 | 19 | if (_modelArray == nil) { 20 | _modelArray = [NSMutableArray array]; 21 | if ([[NSUserDefaults standardUserDefaults] arrayForKey:uploadListName]) { 22 | _modelArray = [SPDocUploadModel mj_objectArrayWithKeyValuesArray:[[NSUserDefaults standardUserDefaults] arrayForKey:uploadListName]]; 23 | } 24 | } 25 | return _modelArray; 26 | } 27 | 28 | 29 | 30 | - (void)addUploadModel:(SPDocUploadModel *)model { 31 | 32 | [self.modelArray addObject:model]; 33 | [self refreshCaches]; 34 | [[NSNotificationCenter defaultCenter] postNotificationName:kSuperUploadFile object:nil]; 35 | } 36 | 37 | - (void)removeUploadModel:(SPDocUploadModel *)model { 38 | 39 | model.isRunning = NO; 40 | [model.dataTask cancel]; 41 | [self cleanPath:model.filePath]; 42 | [self.modelArray removeObject:model]; 43 | [self refreshCaches]; 44 | [[NSNotificationCenter defaultCenter] postNotificationName:kSuperFinishedUpload object:nil]; 45 | if (self.modelArray.count == 0) { 46 | [self postNotice]; 47 | } 48 | 49 | } 50 | 51 | - (void)postNotice { 52 | 53 | [[NSNotificationCenter defaultCenter] postNotificationName:kSuperFinishedUpload object:nil]; 54 | } 55 | 56 | - (void)refreshCaches { 57 | 58 | [[NSUserDefaults standardUserDefaults] setObject:[SPDocUploadModel mj_keyValuesArrayWithObjectArray:self.modelArray ignoredKeys:@[@"progressBlock",@"isRunning",@"dataTask"]] forKey:uploadListName]; 59 | [[NSUserDefaults standardUserDefaults] synchronize]; 60 | } 61 | 62 | - (void)cancelAllUploadOperations { 63 | 64 | for (SPDocUploadModel *docUploadModel in self.modelArray) { 65 | [docUploadModel.dataTask cancel]; 66 | docUploadModel.isRunning = NO; 67 | } 68 | 69 | [self refreshCaches]; 70 | } 71 | 72 | - (void)removeAll { 73 | 74 | [self cancelAllUploadOperations]; 75 | [self.modelArray removeAllObjects]; 76 | [self refreshCaches]; 77 | [self clean]; 78 | [self postNotice]; 79 | 80 | } 81 | 82 | #pragma mark- first upload 断点(NSURL) 83 | - (void)uploadUrl:(NSURL *)mediaUrl withModel:(SPDocUploadModel *)model completion:(void(^)(void))completion { 84 | 85 | int64_t length = [self fileSizeAtPath:mediaUrl]; 86 | NSInteger count = length / (kSuperUploadBlockSize); 87 | NSInteger blockCount = length % (kSuperUploadBlockSize) == 0 ? count : count + 1; 88 | 89 | model.filePath = [self writeToCacheUrl:mediaUrl appendNameString:model.lastPathComponent]; 90 | model.totalCount = blockCount; 91 | model.totalSize = length; 92 | 93 | 94 | NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:mediaUrl.path]; 95 | NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:model.filePath append:YES]; 96 | [outputStream open]; 97 | 98 | for (NSInteger i = 0; i < count ; i ++) { 99 | [handle seekToFileOffset:kSuperUploadBlockSize * i]; 100 | @autoreleasepool { 101 | NSData *blockData = [handle readDataOfLength:kSuperUploadBlockSize]; 102 | [outputStream write:blockData.bytes maxLength:blockData.length]; 103 | blockData = nil; 104 | } 105 | } 106 | [outputStream close]; 107 | [handle closeFile]; 108 | 109 | [self uploadWithModel:model completion:completion]; 110 | 111 | } 112 | 113 | #pragma mark- first upload 断点(NSData) 114 | - (void)uploadData:(NSData *)data withModel:(SPDocUploadModel *)model completion:(void(^)(void))completion { 115 | 116 | NSInteger count = data.length / (kSuperUploadBlockSize); 117 | NSInteger blockCount = data.length % (kSuperUploadBlockSize) == 0 ? count : count + 1; 118 | 119 | model.filePath = [self writeToCacheVideo:data appendNameString:model.lastPathComponent]; 120 | model.totalCount = blockCount; 121 | model.totalSize = data.length; 122 | 123 | [self uploadWithModel:model completion:completion]; 124 | } 125 | 126 | #pragma mark- first upload 127 | - (void)uploadWithModel:(SPDocUploadModel *)model completion:(void(^)(void))completion { 128 | 129 | model.uploadedCount = 0; 130 | model.isRunning = YES; 131 | 132 | NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; 133 | 134 | // 上传序列标识 135 | parameters[@"sequenceNo"] = @0; 136 | // 片大小 137 | parameters[@"blockSize"] = @(kSuperUploadBlockSize); 138 | // 总大小 139 | parameters[@"totFileSize"] = @(model.totalSize); 140 | // 扩展名 141 | parameters[@"suffix"] = model.filePath.pathExtension; 142 | // 参数和接口 143 | NSString *requestUrl = kSuperUploadTestUrl; 144 | 145 | AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 146 | NSURLSessionDataTask *dataTask = [manager POST:requestUrl parameters:parameters constructingBodyWithBlock:^(id _Nonnull formData) { 147 | [formData appendPartWithFileData:[NSData data] name:@"block" fileName:model.filePath.lastPathComponent mimeType:@"application/octet-stream"]; 148 | 149 | } success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { 150 | 151 | NSDictionary *dataDict = responseObject[@"data"]; 152 | model.upToken = dataDict[@"upToken"]; 153 | NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:model.filePath]; 154 | if (handle == nil) { return; } 155 | [self continueUploadWithModel:model]; 156 | [self addUploadModel:model]; 157 | if (completion) { completion();} 158 | 159 | } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { 160 | NSLog(@"SuperNSLog-- %@",error.description); 161 | }]; 162 | 163 | model.dataTask = dataTask; 164 | 165 | } 166 | 167 | #pragma mark- continue upload 168 | - (void)continueUploadWithModel:(SPDocUploadModel *)model { 169 | if (!model.isRunning) { 170 | return; 171 | } 172 | __block NSInteger i = model.uploadedCount; 173 | 174 | NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; 175 | parameters[@"blockSize"] = @(kSuperUploadBlockSize); 176 | parameters[@"totFileSize"] = @(model.totalSize); 177 | parameters[@"suffix"] = model.filePath.pathExtension; 178 | parameters[@"upToken"] = model.upToken; 179 | parameters[@"sequenceNo"] = @(i + 1); 180 | 181 | NSString *requestUrl = kSuperUploadTestUrl; 182 | AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 183 | NSURLSessionDataTask *dataTask = [manager POST:requestUrl parameters:parameters constructingBodyWithBlock:^(id _Nonnull formData) { 184 | 185 | NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:model.filePath]; 186 | [handle seekToFileOffset:kSuperUploadBlockSize * i]; 187 | NSData *blockData = [handle readDataOfLength:kSuperUploadBlockSize]; 188 | [formData appendPartWithFileData:blockData name:@"block" fileName:model.filePath.lastPathComponent mimeType:@"application/octet-stream"]; 189 | [handle closeFile]; 190 | 191 | } success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { 192 | 193 | i ++; 194 | model.uploadedCount = i; 195 | NSDictionary *dataDict = responseObject[@"data"]; 196 | NSString *fileUrl = dataDict[@"fileUrl"]; 197 | if ([fileUrl isKindOfClass:[NSString class]]) { 198 | 199 | [model.parameters setValue:fileUrl forKey:@"fileUrl"]; 200 | [self saveRequest:model]; 201 | 202 | }else { 203 | if (i < model.totalCount) { 204 | [self continueUploadWithModel:model]; 205 | } 206 | } 207 | 208 | } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { 209 | if (model.isRunning) { 210 | [self continueUploadWithModel:model]; 211 | } 212 | }]; 213 | 214 | model.dataTask = dataTask; 215 | } 216 | 217 | 218 | #pragma mark- clean cache file 219 | - (void)clean { 220 | NSString *cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; 221 | NSString *path = [cachesDirectory stringByAppendingPathComponent:@"video"]; 222 | NSFileManager *fileManager = [[NSFileManager alloc] init]; 223 | [fileManager removeItemAtPath:path error:nil]; 224 | } 225 | 226 | - (void)cleanPath:(NSString *)filePath { 227 | 228 | NSFileManager *fileManager = [[NSFileManager alloc] init]; 229 | [fileManager removeItemAtPath:filePath error:nil]; 230 | } 231 | 232 | #pragma mark- write cache file 233 | - (NSString *)writeToCacheVideo:(NSData *)data appendNameString:(NSString *)name { 234 | 235 | NSString *path = [self pathByAppendNameString:name]; 236 | [data writeToFile:path atomically:NO]; 237 | return path; 238 | } 239 | 240 | - (NSString *)writeToCacheUrl:(NSURL *)mediaUrl appendNameString:(NSString *)name { 241 | 242 | NSString *path = [self pathByAppendNameString:name]; 243 | return path; 244 | } 245 | 246 | 247 | - (NSString *)pathByAppendNameString:(NSString *)name { 248 | 249 | NSString *cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; 250 | NSString *createPath = [cachesDirectory stringByAppendingPathComponent:@"video"]; 251 | NSFileManager *fileManager = [[NSFileManager alloc] init]; 252 | [fileManager createDirectoryAtPath:createPath withIntermediateDirectories:YES attributes:nil error:nil]; 253 | NSString *path = [cachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"/video/%.0f%@",[NSDate date].timeIntervalSince1970,name]]; 254 | return path; 255 | } 256 | 257 | 258 | #pragma mark- saveRequest 259 | - (void)saveRequest:(SPDocUploadModel *)model { 260 | 261 | // 操作 262 | 263 | // 处理完毕后 264 | [self removeUploadModel:model]; 265 | } 266 | 267 | // 通过路径获取文件大小 268 | - (long long)fileSizeAtPath:(NSURL *)mediaUrl { 269 | 270 | NSFileManager *manager =[NSFileManager defaultManager]; 271 | if ([manager fileExistsAtPath:mediaUrl.path]){ 272 | return [[manager attributesOfItemAtPath:mediaUrl.path error:nil] fileSize]; 273 | }else { 274 | return 0; 275 | } 276 | 277 | } 278 | 279 | @end 280 | -------------------------------------------------------------------------------- /SPUpload/Controller/SPDocUpListVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPDocUpListVC.h 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SPDocUpListVC : UIViewController 12 | 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /SPUpload/Controller/SPDocUpListVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPDocUpListVC.m 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import "SPDocUpListVC.h" 10 | #import "SPDocUploadModel.h" 11 | #import "SPDocUploadCell.h" 12 | 13 | @interface SPDocUpListVC () 14 | 15 | @property (nonatomic, weak) UITableView *tableView; 16 | 17 | @end 18 | 19 | @implementation SPDocUpListVC 20 | 21 | static NSString *const cellID = @"uploadListCell"; 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | 26 | [self setupTableView]; 27 | 28 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"清空列表" style:UIBarButtonItemStylePlain target:self action:@selector(clean)]; 29 | 30 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadData) name:kSuperFinishedUpload object:nil]; 31 | 32 | self.title = @"上传列表"; 33 | } 34 | 35 | 36 | 37 | - (void)setupTableView { 38 | 39 | UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 0, 0) style:UITableViewStylePlain]; 40 | tableView.backgroundColor = [UIColor whiteColor]; 41 | tableView.delegate = self; 42 | tableView.dataSource = self; 43 | tableView.rowHeight = 80; 44 | tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 45 | [tableView registerClass:[SPDocUploadCell class] forCellReuseIdentifier:cellID]; 46 | [self.view addSubview:tableView]; 47 | [tableView mas_makeConstraints:^(MASConstraintMaker *make) { 48 | make.top.bottom.left.right.equalTo(@0); 49 | }]; 50 | self.tableView = tableView; 51 | } 52 | 53 | #pragma mark- UITableViewDataSource 54 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 55 | 56 | return [SPUploadManager shareUploadManager].modelArray.count ; 57 | } 58 | 59 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 60 | 61 | SPDocUploadCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; 62 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 63 | cell.reloadDataBlock = ^{[self reloadData];}; 64 | SPDocUploadModel *docUploadModel = [SPUploadManager shareUploadManager].modelArray[indexPath.row]; 65 | cell.docUploadModel = docUploadModel; 66 | 67 | 68 | return cell; 69 | } 70 | 71 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 72 | 73 | SPDocUploadModel *docUploadModel = [SPUploadManager shareUploadManager].modelArray[indexPath.row]; 74 | NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:docUploadModel.filePath]; 75 | if (handle == nil) { 76 | NSLog(@"SuperNSLog-- 源文件不存在或路径已经改变"); 77 | return; 78 | } 79 | docUploadModel.isRunning = !docUploadModel.isRunning; 80 | if (docUploadModel.isRunning) { 81 | if (docUploadModel.dataTask.state == NSURLSessionTaskStateSuspended) { 82 | [docUploadModel.dataTask resume]; 83 | }else { 84 | [[SPUploadManager shareUploadManager] continueUploadWithModel:docUploadModel]; 85 | } 86 | 87 | }else { 88 | [docUploadModel.dataTask suspend]; 89 | } 90 | 91 | [self reloadData]; 92 | 93 | 94 | } 95 | 96 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 97 | 98 | SPDocUploadModel *docUploadModel = [SPUploadManager shareUploadManager].modelArray[indexPath.row]; 99 | [[SPUploadManager shareUploadManager] removeUploadModel:docUploadModel]; 100 | } 101 | 102 | 103 | - (void)reloadData { 104 | 105 | [self.tableView reloadData]; 106 | } 107 | 108 | - (void)dealloc { 109 | 110 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 111 | } 112 | 113 | - (void)clean { 114 | 115 | [[SPUploadManager shareUploadManager] removeAll]; 116 | [self reloadData]; 117 | 118 | } 119 | 120 | 121 | 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /SPUpload/Model/SPDocUploadModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPDocUploadModel.h 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, SPFileType) { 12 | SPFileTypePhoto, 13 | SPFileTypeVideo, 14 | SPFileTypeDocument 15 | }; 16 | 17 | @interface SPDocUploadModel : NSObject 18 | 19 | // 方便操作(暂停取消)正在上传的文件 20 | @property (nonatomic, strong) NSURLSessionDataTask *dataTask; 21 | // 总大小 22 | @property (nonatomic, assign) int64_t totalSize; 23 | // 总片数 24 | @property (nonatomic, assign) NSInteger totalCount; 25 | // 已上传片数 26 | @property (nonatomic, assign) NSInteger uploadedCount; 27 | // 上传所需参数 28 | @property (nonatomic, copy) NSString *upToken; 29 | // 上传状态标识, 记录是上传中还是暂停 30 | @property (nonatomic, assign) BOOL isRunning; 31 | // 缓存文件路径 32 | @property (nonatomic, copy) NSString *filePath; 33 | // 用来保存文件名使用 34 | @property (nonatomic, copy) NSString *lastPathComponent; 35 | 36 | // 以下属性用于给上传列表界面赋值 37 | @property (nonatomic, assign) SPFileType fileType; 38 | @property (nonatomic, copy) NSString *title; 39 | @property (nonatomic, copy) NSString *progressLableText; 40 | @property (nonatomic, assign) CGFloat uploadPercent; 41 | @property (nonatomic, copy) void(^progressBlock)(CGFloat uploadPersent,NSString *progressLableText); 42 | 43 | // 接下来调用的url 44 | @property (nonatomic, copy) NSString *requestUrl; 45 | // 保存上传成功后调用保存接口的参数 46 | @property (nonatomic, strong) NSMutableDictionary *parameters; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /SPUpload/Model/SPDocUploadModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPDocUploadModel.m 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import "SPDocUploadModel.h" 10 | 11 | @implementation SPDocUploadModel 12 | 13 | - (void)setUploadedCount:(NSInteger)uploadedCount { 14 | 15 | _uploadedCount = uploadedCount; 16 | 17 | self.uploadPercent = (CGFloat)uploadedCount / self.totalCount; 18 | self.progressLableText = [NSString stringWithFormat:@"%.2fMB/%.2fMB",self.totalSize * self.uploadPercent /1024.0/1024.0,self.totalSize/1024.0/1024.0]; 19 | if (self.progressBlock) { 20 | self.progressBlock(self.uploadPercent,self.progressLableText); 21 | } 22 | 23 | [[SPUploadManager shareUploadManager] refreshCaches]; 24 | 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /SPUpload/View/SPDocUploadCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPDocUploadCell.h 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SPDocUploadModel; 12 | 13 | @interface SPDocUploadCell : UITableViewCell 14 | 15 | @property (nonatomic, strong) SPDocUploadModel *docUploadModel; 16 | @property (nonatomic, copy) void(^reloadDataBlock)(void); 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /SPUpload/View/SPDocUploadCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SPDocUploadCell.m 3 | // 4 | // 5 | // Created by SPSuper on 2017/7/12. 6 | // Copyright © 2017年 Super. All rights reserved. 7 | // 8 | 9 | #import "SPDocUploadCell.h" 10 | #import "SPDocUploadModel.h" 11 | #import "SPDocUpListVC.h" 12 | 13 | @interface SPDocUploadCell () 14 | 15 | @property (nonatomic, weak) UIImageView *typeImangeView ; 16 | @property (nonatomic, weak) UILabel *fileTitlelabel; 17 | @property (nonatomic, weak) UILabel *progressLabel; 18 | @property (nonatomic, weak) UIProgressView *progressView; 19 | @property (nonatomic, weak) UILabel *runningLabel; 20 | 21 | 22 | 23 | @end 24 | 25 | @implementation SPDocUploadCell 26 | 27 | 28 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 29 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 30 | 31 | UIImageView *typeImangeView = [[UIImageView alloc] init]; 32 | [self.contentView addSubview:typeImangeView]; 33 | typeImangeView.contentMode = UIViewContentModeScaleAspectFill; 34 | typeImangeView.layer.masksToBounds = YES; 35 | self.typeImangeView = typeImangeView; 36 | [typeImangeView mas_makeConstraints:^(MASConstraintMaker *make) { 37 | make.left.equalTo(@10); 38 | make.centerY.equalTo(self.mas_centerY); 39 | make.width.height.equalTo(@60); 40 | }]; 41 | 42 | UILabel *fileTitlelabel = [[UILabel alloc] init]; 43 | fileTitlelabel.textColor = [UIColor blackColor]; 44 | [self.contentView addSubview:fileTitlelabel]; 45 | self.fileTitlelabel = fileTitlelabel; 46 | [fileTitlelabel mas_makeConstraints:^(MASConstraintMaker *make) { 47 | make.right.equalTo(@-20); 48 | make.top.equalTo(@15); 49 | make.left.equalTo(typeImangeView.mas_right).offset(20); 50 | make.height.equalTo(@25); 51 | }]; 52 | 53 | UILabel *progressLabel = [[UILabel alloc] init]; 54 | progressLabel.textColor = [UIColor grayColor]; 55 | progressLabel.font = [UIFont systemFontOfSize:12];; 56 | [self.contentView addSubview:progressLabel]; 57 | self.progressLabel = progressLabel; 58 | [progressLabel mas_makeConstraints:^(MASConstraintMaker *make) { 59 | make.top.equalTo(fileTitlelabel.mas_bottom); 60 | make.left.equalTo(fileTitlelabel.mas_left); 61 | make.width.equalTo(fileTitlelabel.mas_width); 62 | make.height.equalTo(@20); 63 | }]; 64 | 65 | UIProgressView *progressView = [[UIProgressView alloc] init]; 66 | progressView.transform = CGAffineTransformMakeScale(1.0, 1.5); 67 | [self.contentView addSubview:progressView]; 68 | self.progressView = progressView; 69 | [progressView mas_makeConstraints:^(MASConstraintMaker *make) { 70 | make.top.equalTo(progressLabel.mas_bottom).offset(5); 71 | make.left.equalTo(progressLabel.mas_left); 72 | make.width.equalTo(progressLabel.mas_width); 73 | }]; 74 | 75 | UILabel *runningLabel = [[UILabel alloc] init]; 76 | runningLabel.textColor = [UIColor lightGrayColor]; 77 | runningLabel.textAlignment = NSTextAlignmentRight; 78 | runningLabel.font = [UIFont systemFontOfSize:12];; 79 | [self.contentView addSubview:runningLabel]; 80 | self.runningLabel = runningLabel; 81 | [runningLabel mas_makeConstraints:^(MASConstraintMaker *make) { 82 | make.top.equalTo(fileTitlelabel.mas_bottom); 83 | make.right.equalTo(self.contentView.mas_right).offset(-20); 84 | make.width.equalTo(@100); 85 | make.height.equalTo(@20); 86 | 87 | }]; 88 | 89 | UIView *sepView = [[UIView alloc] init]; 90 | [self addSubview:sepView]; 91 | sepView.backgroundColor = [UIColor lightGrayColor]; 92 | [sepView mas_makeConstraints:^(MASConstraintMaker *make) { 93 | make.left.right.bottom.equalTo(@0); 94 | make.height.equalTo(@1); 95 | }]; 96 | 97 | } 98 | 99 | return self; 100 | } 101 | 102 | 103 | 104 | - (void)setDocUploadModel:(SPDocUploadModel *)docUploadModel { 105 | 106 | docUploadModel.progressBlock = ^(CGFloat uploadPersent,NSString *progressLableText){ 107 | self.progressLabel.text = progressLableText; 108 | self.progressView.progress = uploadPersent; 109 | [[SPUploadManager shareUploadManager] refreshCaches]; 110 | }; 111 | 112 | self.progressLabel.text = docUploadModel.progressLableText; 113 | self.progressView.progress = docUploadModel.uploadPercent; 114 | 115 | switch (docUploadModel.fileType) { 116 | 117 | case SPFileTypePhoto: 118 | _typeImangeView.image = [UIImage imageWithContentsOfFile:docUploadModel.filePath]; 119 | break; 120 | case SPFileTypeVideo: 121 | _typeImangeView.image = [UIImage imageNamed:@"video"]; 122 | break; 123 | 124 | default: 125 | _typeImangeView.image = [UIImage imageNamed:@"document"]; 126 | break; 127 | } 128 | 129 | if (docUploadModel.isRunning) { 130 | self.runningLabel.text = @"正在上传..."; 131 | }else { 132 | self.runningLabel.text = @"已暂停"; 133 | } 134 | self.fileTitlelabel.text = docUploadModel.title; 135 | _docUploadModel = docUploadModel; 136 | } 137 | 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /SPUploadDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7F6813A305F60800250526F7 /* libPods-SPUploadDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4918B061372349DD75C366DC /* libPods-SPUploadDemo.a */; }; 11 | BF2CF7A21FF0AA8700263A24 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7A11FF0AA8700263A24 /* AppDelegate.m */; }; 12 | BF2CF7A51FF0AA8700263A24 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7A41FF0AA8700263A24 /* ViewController.m */; }; 13 | BF2CF7A81FF0AA8700263A24 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF2CF7A61FF0AA8700263A24 /* Main.storyboard */; }; 14 | BF2CF7AA1FF0AA8700263A24 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF2CF7A91FF0AA8700263A24 /* Assets.xcassets */; }; 15 | BF2CF7AD1FF0AA8700263A24 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BF2CF7AB1FF0AA8700263A24 /* LaunchScreen.storyboard */; }; 16 | BF2CF7B01FF0AA8700263A24 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7AF1FF0AA8700263A24 /* main.m */; }; 17 | BF2CF7DA1FF0D33C00263A24 /* SPDocUploadModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7D11FF0CEB100263A24 /* SPDocUploadModel.m */; }; 18 | BF2CF7DB1FF0D34000263A24 /* SPDocUploadCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7D31FF0CEBA00263A24 /* SPDocUploadCell.m */; }; 19 | BF2CF7DC1FF0D34200263A24 /* SPDocUpListVC.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7CD1FF0CEA600263A24 /* SPDocUpListVC.m */; }; 20 | BF2CF7E21FF0D78900263A24 /* SPUploadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7E01FF0D78900263A24 /* SPUploadManager.m */; }; 21 | BF2CF7E61FF0D7BE00263A24 /* SPGlobalConst.m in Sources */ = {isa = PBXBuildFile; fileRef = BF2CF7E51FF0D7BE00263A24 /* SPGlobalConst.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 4918B061372349DD75C366DC /* libPods-SPUploadDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SPUploadDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | 8FA8F478DDBB2B247E0F9BE8 /* Pods-SPUploadDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SPUploadDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SPUploadDemo/Pods-SPUploadDemo.debug.xcconfig"; sourceTree = ""; }; 27 | BF2CF79D1FF0AA8700263A24 /* SPUploadDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SPUploadDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | BF2CF7A01FF0AA8700263A24 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 29 | BF2CF7A11FF0AA8700263A24 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 30 | BF2CF7A31FF0AA8700263A24 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 31 | BF2CF7A41FF0AA8700263A24 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 32 | BF2CF7A71FF0AA8700263A24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 33 | BF2CF7A91FF0AA8700263A24 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 34 | BF2CF7AC1FF0AA8700263A24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 35 | BF2CF7AE1FF0AA8700263A24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | BF2CF7AF1FF0AA8700263A24 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 37 | BF2CF7CD1FF0CEA600263A24 /* SPDocUpListVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPDocUpListVC.m; sourceTree = ""; }; 38 | BF2CF7CE1FF0CEA600263A24 /* SPDocUpListVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPDocUpListVC.h; sourceTree = ""; }; 39 | BF2CF7D01FF0CEB100263A24 /* SPDocUploadModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPDocUploadModel.h; sourceTree = ""; }; 40 | BF2CF7D11FF0CEB100263A24 /* SPDocUploadModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPDocUploadModel.m; sourceTree = ""; }; 41 | BF2CF7D31FF0CEBA00263A24 /* SPDocUploadCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPDocUploadCell.m; sourceTree = ""; }; 42 | BF2CF7D41FF0CEBA00263A24 /* SPDocUploadCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPDocUploadCell.h; sourceTree = ""; }; 43 | BF2CF7DF1FF0D78900263A24 /* SPUploadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPUploadManager.h; sourceTree = ""; }; 44 | BF2CF7E01FF0D78900263A24 /* SPUploadManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPUploadManager.m; sourceTree = ""; }; 45 | BF2CF7E11FF0D78900263A24 /* SPSingleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPSingleton.h; sourceTree = ""; }; 46 | BF2CF7E41FF0D7BE00263A24 /* SPGlobalConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPGlobalConst.h; sourceTree = ""; }; 47 | BF2CF7E51FF0D7BE00263A24 /* SPGlobalConst.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPGlobalConst.m; sourceTree = ""; }; 48 | BF2CF7E91FF0D83700263A24 /* SPPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SPPrefixHeader.pch; sourceTree = ""; }; 49 | DB7A82E96BC1E4949E09DAB3 /* Pods-SPUploadDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SPUploadDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-SPUploadDemo/Pods-SPUploadDemo.release.xcconfig"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | BF2CF79A1FF0AA8700263A24 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 7F6813A305F60800250526F7 /* libPods-SPUploadDemo.a in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | A903A53A4852CD8825B87697 /* Pods */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 8FA8F478DDBB2B247E0F9BE8 /* Pods-SPUploadDemo.debug.xcconfig */, 68 | DB7A82E96BC1E4949E09DAB3 /* Pods-SPUploadDemo.release.xcconfig */, 69 | ); 70 | name = Pods; 71 | sourceTree = ""; 72 | }; 73 | BF2CF7941FF0AA8700263A24 = { 74 | isa = PBXGroup; 75 | children = ( 76 | BF2CF79F1FF0AA8700263A24 /* SPUploadDemo */, 77 | BF2CF79E1FF0AA8700263A24 /* Products */, 78 | A903A53A4852CD8825B87697 /* Pods */, 79 | EF2AC2EF4AC1C423E4AE83CD /* Frameworks */, 80 | ); 81 | sourceTree = ""; 82 | }; 83 | BF2CF79E1FF0AA8700263A24 /* Products */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | BF2CF79D1FF0AA8700263A24 /* SPUploadDemo.app */, 87 | ); 88 | name = Products; 89 | sourceTree = ""; 90 | }; 91 | BF2CF79F1FF0AA8700263A24 /* SPUploadDemo */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | BF2CF7B81FF0AB2400263A24 /* SPUpload */, 95 | BF2CF7DE1FF0D78900263A24 /* SPTool */, 96 | BF2CF7E31FF0D79D00263A24 /* SPGlobalFile */, 97 | BF2CF7A01FF0AA8700263A24 /* AppDelegate.h */, 98 | BF2CF7A11FF0AA8700263A24 /* AppDelegate.m */, 99 | BF2CF7A31FF0AA8700263A24 /* ViewController.h */, 100 | BF2CF7A41FF0AA8700263A24 /* ViewController.m */, 101 | BF2CF7A61FF0AA8700263A24 /* Main.storyboard */, 102 | BF2CF7A91FF0AA8700263A24 /* Assets.xcassets */, 103 | BF2CF7AB1FF0AA8700263A24 /* LaunchScreen.storyboard */, 104 | BF2CF7AE1FF0AA8700263A24 /* Info.plist */, 105 | BF2CF7AF1FF0AA8700263A24 /* main.m */, 106 | ); 107 | path = SPUploadDemo; 108 | sourceTree = ""; 109 | }; 110 | BF2CF7B81FF0AB2400263A24 /* SPUpload */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | BF2CF7B91FF0AB2400263A24 /* Controller */, 114 | BF2CF7BA1FF0AB2400263A24 /* Model */, 115 | BF2CF7BB1FF0AB2400263A24 /* View */, 116 | ); 117 | path = SPUpload; 118 | sourceTree = SOURCE_ROOT; 119 | }; 120 | BF2CF7B91FF0AB2400263A24 /* Controller */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | BF2CF7CE1FF0CEA600263A24 /* SPDocUpListVC.h */, 124 | BF2CF7CD1FF0CEA600263A24 /* SPDocUpListVC.m */, 125 | ); 126 | path = Controller; 127 | sourceTree = ""; 128 | }; 129 | BF2CF7BA1FF0AB2400263A24 /* Model */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | BF2CF7D01FF0CEB100263A24 /* SPDocUploadModel.h */, 133 | BF2CF7D11FF0CEB100263A24 /* SPDocUploadModel.m */, 134 | ); 135 | path = Model; 136 | sourceTree = ""; 137 | }; 138 | BF2CF7BB1FF0AB2400263A24 /* View */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | BF2CF7D41FF0CEBA00263A24 /* SPDocUploadCell.h */, 142 | BF2CF7D31FF0CEBA00263A24 /* SPDocUploadCell.m */, 143 | ); 144 | path = View; 145 | sourceTree = ""; 146 | }; 147 | BF2CF7DE1FF0D78900263A24 /* SPTool */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | BF2CF7DF1FF0D78900263A24 /* SPUploadManager.h */, 151 | BF2CF7E01FF0D78900263A24 /* SPUploadManager.m */, 152 | BF2CF7E11FF0D78900263A24 /* SPSingleton.h */, 153 | ); 154 | path = SPTool; 155 | sourceTree = SOURCE_ROOT; 156 | }; 157 | BF2CF7E31FF0D79D00263A24 /* SPGlobalFile */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | BF2CF7E41FF0D7BE00263A24 /* SPGlobalConst.h */, 161 | BF2CF7E51FF0D7BE00263A24 /* SPGlobalConst.m */, 162 | BF2CF7E91FF0D83700263A24 /* SPPrefixHeader.pch */, 163 | ); 164 | path = SPGlobalFile; 165 | sourceTree = SOURCE_ROOT; 166 | }; 167 | EF2AC2EF4AC1C423E4AE83CD /* Frameworks */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 4918B061372349DD75C366DC /* libPods-SPUploadDemo.a */, 171 | ); 172 | name = Frameworks; 173 | sourceTree = ""; 174 | }; 175 | /* End PBXGroup section */ 176 | 177 | /* Begin PBXNativeTarget section */ 178 | BF2CF79C1FF0AA8700263A24 /* SPUploadDemo */ = { 179 | isa = PBXNativeTarget; 180 | buildConfigurationList = BF2CF7B31FF0AA8700263A24 /* Build configuration list for PBXNativeTarget "SPUploadDemo" */; 181 | buildPhases = ( 182 | DAFB0C303F347B90A7FE0E68 /* [CP] Check Pods Manifest.lock */, 183 | BF2CF7991FF0AA8700263A24 /* Sources */, 184 | BF2CF79A1FF0AA8700263A24 /* Frameworks */, 185 | BF2CF79B1FF0AA8700263A24 /* Resources */, 186 | ); 187 | buildRules = ( 188 | ); 189 | dependencies = ( 190 | ); 191 | name = SPUploadDemo; 192 | productName = SPUploadDemo; 193 | productReference = BF2CF79D1FF0AA8700263A24 /* SPUploadDemo.app */; 194 | productType = "com.apple.product-type.application"; 195 | }; 196 | /* End PBXNativeTarget section */ 197 | 198 | /* Begin PBXProject section */ 199 | BF2CF7951FF0AA8700263A24 /* Project object */ = { 200 | isa = PBXProject; 201 | attributes = { 202 | LastUpgradeCheck = 0920; 203 | ORGANIZATIONNAME = YJTSuper; 204 | TargetAttributes = { 205 | BF2CF79C1FF0AA8700263A24 = { 206 | CreatedOnToolsVersion = 9.2; 207 | ProvisioningStyle = Automatic; 208 | }; 209 | }; 210 | }; 211 | buildConfigurationList = BF2CF7981FF0AA8700263A24 /* Build configuration list for PBXProject "SPUploadDemo" */; 212 | compatibilityVersion = "Xcode 8.0"; 213 | developmentRegion = en; 214 | hasScannedForEncodings = 0; 215 | knownRegions = ( 216 | en, 217 | Base, 218 | ); 219 | mainGroup = BF2CF7941FF0AA8700263A24; 220 | productRefGroup = BF2CF79E1FF0AA8700263A24 /* Products */; 221 | projectDirPath = ""; 222 | projectRoot = ""; 223 | targets = ( 224 | BF2CF79C1FF0AA8700263A24 /* SPUploadDemo */, 225 | ); 226 | }; 227 | /* End PBXProject section */ 228 | 229 | /* Begin PBXResourcesBuildPhase section */ 230 | BF2CF79B1FF0AA8700263A24 /* Resources */ = { 231 | isa = PBXResourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | BF2CF7AD1FF0AA8700263A24 /* LaunchScreen.storyboard in Resources */, 235 | BF2CF7AA1FF0AA8700263A24 /* Assets.xcassets in Resources */, 236 | BF2CF7A81FF0AA8700263A24 /* Main.storyboard in Resources */, 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | }; 240 | /* End PBXResourcesBuildPhase section */ 241 | 242 | /* Begin PBXShellScriptBuildPhase section */ 243 | DAFB0C303F347B90A7FE0E68 /* [CP] Check Pods Manifest.lock */ = { 244 | isa = PBXShellScriptBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | inputPaths = ( 249 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 250 | "${PODS_ROOT}/Manifest.lock", 251 | ); 252 | name = "[CP] Check Pods Manifest.lock"; 253 | outputPaths = ( 254 | "$(DERIVED_FILE_DIR)/Pods-SPUploadDemo-checkManifestLockResult.txt", 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | shellPath = /bin/sh; 258 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 259 | showEnvVarsInLog = 0; 260 | }; 261 | /* End PBXShellScriptBuildPhase section */ 262 | 263 | /* Begin PBXSourcesBuildPhase section */ 264 | BF2CF7991FF0AA8700263A24 /* Sources */ = { 265 | isa = PBXSourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | BF2CF7A51FF0AA8700263A24 /* ViewController.m in Sources */, 269 | BF2CF7B01FF0AA8700263A24 /* main.m in Sources */, 270 | BF2CF7E61FF0D7BE00263A24 /* SPGlobalConst.m in Sources */, 271 | BF2CF7E21FF0D78900263A24 /* SPUploadManager.m in Sources */, 272 | BF2CF7DB1FF0D34000263A24 /* SPDocUploadCell.m in Sources */, 273 | BF2CF7A21FF0AA8700263A24 /* AppDelegate.m in Sources */, 274 | BF2CF7DA1FF0D33C00263A24 /* SPDocUploadModel.m in Sources */, 275 | BF2CF7DC1FF0D34200263A24 /* SPDocUpListVC.m in Sources */, 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXSourcesBuildPhase section */ 280 | 281 | /* Begin PBXVariantGroup section */ 282 | BF2CF7A61FF0AA8700263A24 /* Main.storyboard */ = { 283 | isa = PBXVariantGroup; 284 | children = ( 285 | BF2CF7A71FF0AA8700263A24 /* Base */, 286 | ); 287 | name = Main.storyboard; 288 | sourceTree = ""; 289 | }; 290 | BF2CF7AB1FF0AA8700263A24 /* LaunchScreen.storyboard */ = { 291 | isa = PBXVariantGroup; 292 | children = ( 293 | BF2CF7AC1FF0AA8700263A24 /* Base */, 294 | ); 295 | name = LaunchScreen.storyboard; 296 | sourceTree = ""; 297 | }; 298 | /* End PBXVariantGroup section */ 299 | 300 | /* Begin XCBuildConfiguration section */ 301 | BF2CF7B11FF0AA8700263A24 /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | CLANG_ANALYZER_NONNULL = YES; 306 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 316 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 323 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 324 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 325 | CLANG_WARN_STRICT_PROTOTYPES = YES; 326 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 327 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | CODE_SIGN_IDENTITY = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu11; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | ONLY_ACTIVE_ARCH = YES; 352 | SDKROOT = iphoneos; 353 | }; 354 | name = Debug; 355 | }; 356 | BF2CF7B21FF0AA8700263A24 /* Release */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ALWAYS_SEARCH_USER_PATHS = NO; 360 | CLANG_ANALYZER_NONNULL = YES; 361 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 371 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 378 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 379 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 380 | CLANG_WARN_STRICT_PROTOTYPES = YES; 381 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 382 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | CODE_SIGN_IDENTITY = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu11; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 394 | GCC_WARN_UNDECLARED_SELECTOR = YES; 395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 396 | GCC_WARN_UNUSED_FUNCTION = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 399 | MTL_ENABLE_DEBUG_INFO = NO; 400 | SDKROOT = iphoneos; 401 | VALIDATE_PRODUCT = YES; 402 | }; 403 | name = Release; 404 | }; 405 | BF2CF7B41FF0AA8700263A24 /* Debug */ = { 406 | isa = XCBuildConfiguration; 407 | baseConfigurationReference = 8FA8F478DDBB2B247E0F9BE8 /* Pods-SPUploadDemo.debug.xcconfig */; 408 | buildSettings = { 409 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 410 | CODE_SIGN_STYLE = Automatic; 411 | DEVELOPMENT_TEAM = 86WPXA9A4C; 412 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 413 | GCC_PREFIX_HEADER = SPGlobalFile/SPPrefixHeader.pch; 414 | INFOPLIST_FILE = SPUploadDemo/Info.plist; 415 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 416 | PRODUCT_BUNDLE_IDENTIFIER = Supertest.SPUploadDemo; 417 | PRODUCT_NAME = "$(TARGET_NAME)"; 418 | TARGETED_DEVICE_FAMILY = "1,2"; 419 | }; 420 | name = Debug; 421 | }; 422 | BF2CF7B51FF0AA8700263A24 /* Release */ = { 423 | isa = XCBuildConfiguration; 424 | baseConfigurationReference = DB7A82E96BC1E4949E09DAB3 /* Pods-SPUploadDemo.release.xcconfig */; 425 | buildSettings = { 426 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 427 | CODE_SIGN_STYLE = Automatic; 428 | DEVELOPMENT_TEAM = 86WPXA9A4C; 429 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 430 | GCC_PREFIX_HEADER = SPGlobalFile/SPPrefixHeader.pch; 431 | INFOPLIST_FILE = SPUploadDemo/Info.plist; 432 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 433 | PRODUCT_BUNDLE_IDENTIFIER = Supertest.SPUploadDemo; 434 | PRODUCT_NAME = "$(TARGET_NAME)"; 435 | TARGETED_DEVICE_FAMILY = "1,2"; 436 | }; 437 | name = Release; 438 | }; 439 | /* End XCBuildConfiguration section */ 440 | 441 | /* Begin XCConfigurationList section */ 442 | BF2CF7981FF0AA8700263A24 /* Build configuration list for PBXProject "SPUploadDemo" */ = { 443 | isa = XCConfigurationList; 444 | buildConfigurations = ( 445 | BF2CF7B11FF0AA8700263A24 /* Debug */, 446 | BF2CF7B21FF0AA8700263A24 /* Release */, 447 | ); 448 | defaultConfigurationIsVisible = 0; 449 | defaultConfigurationName = Release; 450 | }; 451 | BF2CF7B31FF0AA8700263A24 /* Build configuration list for PBXNativeTarget "SPUploadDemo" */ = { 452 | isa = XCConfigurationList; 453 | buildConfigurations = ( 454 | BF2CF7B41FF0AA8700263A24 /* Debug */, 455 | BF2CF7B51FF0AA8700263A24 /* Release */, 456 | ); 457 | defaultConfigurationIsVisible = 0; 458 | defaultConfigurationName = Release; 459 | }; 460 | /* End XCConfigurationList section */ 461 | }; 462 | rootObject = BF2CF7951FF0AA8700263A24 /* Project object */; 463 | } 464 | -------------------------------------------------------------------------------- /SPUploadDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SPUploadDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SPUploadDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SPUploadDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SPUploadDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SPUploadDemo 4 | // 5 | // Created by SPSuper on 2017/12/25. 6 | // Copyright © 2017年 SPSuper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /SPUploadDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SPUploadDemo 4 | // 5 | // Created by SPSuper on 2017/12/25. 6 | // Copyright © 2017年 SPSuper. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /SPUploadDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /SPUploadDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SPUploadDemo/Assets.xcassets/document.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "document-2.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SPUploadDemo/Assets.xcassets/document.imageset/document-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superxjhw/SPUploadTool/165757dc2d277ff72f18c86d891fbfff68df73de/SPUploadDemo/Assets.xcassets/document.imageset/document-2.png -------------------------------------------------------------------------------- /SPUploadDemo/Assets.xcassets/video.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "video-2.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SPUploadDemo/Assets.xcassets/video.imageset/video-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superxjhw/SPUploadTool/165757dc2d277ff72f18c86d891fbfff68df73de/SPUploadDemo/Assets.xcassets/video.imageset/video-2.png -------------------------------------------------------------------------------- /SPUploadDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /SPUploadDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 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 | -------------------------------------------------------------------------------- /SPUploadDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleLocalizations 14 | 15 | zh_CN 16 | 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSCameraUsageDescription 28 | 请允许访问相机 29 | NSPhotoLibraryUsageDescription 30 | 请允许访问相册 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UISupportedInterfaceOrientations 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | UISupportedInterfaceOrientations~ipad 46 | 47 | UIInterfaceOrientationPortrait 48 | UIInterfaceOrientationPortraitUpsideDown 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /SPUploadDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // SPUploadDemo 4 | // 5 | // Created by SPSuper on 2017/12/25. 6 | // Copyright © 2017年 SPSuper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /SPUploadDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // SPUploadDemo 4 | // 5 | // Created by SPSuper on 2017/12/25. 6 | // Copyright © 2017年 SPSuper. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "SPDocUpListVC.h" 11 | #import "SPDocUploadModel.h" 12 | 13 | 14 | @interface ViewController () 15 | 16 | @property (nonatomic, copy) NSURL *mediaUrl; 17 | @property (nonatomic, assign) SPFileType fileType; 18 | @property (nonatomic, strong) UIImage *selectImage; 19 | 20 | @end 21 | 22 | @implementation ViewController 23 | 24 | - (IBAction)uploadButtonClick:(UIButton *)sender { 25 | 26 | 27 | // UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 28 | 29 | //包含视频 30 | UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera; 31 | if (![UIImagePickerController isSourceTypeAvailable:sourceType]) { 32 | NSLog(@"SuperNSLog-- 请允许访问手机相册"); 33 | return; 34 | } 35 | 36 | UIImagePickerController *picker = [[UIImagePickerController alloc] init]; 37 | picker.delegate = self; 38 | picker.allowsEditing = NO; 39 | picker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];; 40 | 41 | [self presentViewController:picker animated:YES completion:nil]; 42 | 43 | } 44 | 45 | #pragma mark - UIImagePickerControllerDelegate 46 | -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ 47 | 48 | [self dismissViewControllerAnimated:YES completion:nil]; 49 | if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:( NSString *)kUTTypeImage]) { 50 | self.fileType = SPFileTypePhoto; 51 | self.selectImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 52 | self.mediaUrl = [info objectForKey:UIImagePickerControllerReferenceURL]; 53 | }else { 54 | self.fileType = SPFileTypeVideo; 55 | self.mediaUrl = [info objectForKey:UIImagePickerControllerMediaURL]; 56 | } 57 | 58 | [self upload]; 59 | 60 | 61 | 62 | } 63 | 64 | - (void)upload { 65 | 66 | SPDocUploadModel *model = [[SPDocUploadModel alloc] init]; 67 | model.title = @"上传文件测试"; 68 | model.lastPathComponent = self.mediaUrl.lastPathComponent; 69 | model.fileType = self.fileType; 70 | // 保存上传成功后 接下来调用接口的参数的url \ 71 | 这边app上传列表是统一的,文件服务器返回fileUrl后直接拿到url调用接下来的保存接口 72 | model.requestUrl = nil; 73 | model.parameters = nil; 74 | 75 | NSData *data; 76 | if (self.fileType == SPFileTypePhoto) { 77 | data = UIImageJPEGRepresentation(self.selectImage, 1); 78 | [[SPUploadManager shareUploadManager] uploadData:data withModel:model completion:^{ 79 | [self myUploadListItemClick:nil]; 80 | }]; 81 | }else { 82 | [[SPUploadManager shareUploadManager] uploadUrl:self.mediaUrl withModel:model completion:^{ 83 | [self myUploadListItemClick:nil]; 84 | }]; 85 | } 86 | 87 | } 88 | 89 | 90 | - (IBAction)myUploadListItemClick:(id)sender { 91 | 92 | SPDocUpListVC *uploadListVC = [[SPDocUpListVC alloc] init]; 93 | [self.navigationController pushViewController:uploadListVC animated:YES]; 94 | 95 | } 96 | 97 | 98 | 99 | 100 | 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /SPUploadDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SPUploadDemo 4 | // 5 | // Created by SPSuper on 2017/12/25. 6 | // Copyright © 2017年 SPSuper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /demo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superxjhw/SPUploadTool/165757dc2d277ff72f18c86d891fbfff68df73de/demo.PNG --------------------------------------------------------------------------------