最近的工做是負責寫埋點 SDK,學到了不少知識,不單單是 iOS 方面的,還包括
JavaScript
、NodeJS
、大數據
等方面的一些知識,有時間會把本身學到的知識所有記錄下來,一則是加深印象,二是若是剛好遇到有須要的人,但願能提供一些思路。html
爲何要用表單格式上傳數據到 OSS,你們知道,若是借用 AliyunOSSiOS 的話,會很是 easy 且輕鬆搞定 OSS 數據上傳,那麼爲何非要拼接成表單格式上傳到 OSS 呢?ios
這就和具體需求有關了。git
咱們的需求是,爲公司的幾個 APP 作埋點 SDK,考慮到這幾個 APP 都有可能使用 AliyunOSSiOS,那麼爲了不衝突,兼容自己已集成 AliyunOSSiOS 的 APP,咱們的埋點 SDK 就不能再集成 AliyunOSSiOS 了,因而就選擇了表單格式上傳。github
[NNNetworking requestWithURL:@"獲取簽名的接口" params:@{@"key":@"value"} success:^(id _Nullable responseObject) {
if (responseObject) {
NSDictionary *origDict = responseObject;
NSString *statusCode = origDict[@"statusCode"];
if ([statusCode isEqualToString:@"200"]) {
NSDictionary *resultDict = origDict[@"result"];
NSString *policy = resultDict[@"policy"];
NSString *OSSAccessKeyId = resultDict[@"OSSAccessKeyId"];
NSString *signature = resultDict[@"signature"];
NSString *key = resultDict[@"dirPath"];
NSMutableDictionary *parameterDict = [[NSMutableDictionary alloc]init];
[parameterDict setValue:OSSAccessKeyId forKey:@"OSSAccessKeyId"];
[parameterDict setValue:policy forKey:@"policy"];
[parameterDict setValue:signature forKey:@"signature"];
[parameterDict setValue:key forKey:@"key"];
// 上傳數據到 OSS
[NNNetworking uploadOSSWithParameter:parameterDict uploadDataArray:@[] success:^(id _Nonnull obj) {
} fail:^(NSError * _Nonnull error) {
}];
}
}
} failure:^(NSError * _Nullable error) {
}];
複製代碼
因爲本身作的自己就是 SDK,因此強制不能使用第三方框架,好比經常使用的網絡框架 AFNetworking 或 Alamofire 都不能使用。bash
+ (void)uploadOSSWithParameter:(NSDictionary *)parameterDict uploadDataArray:(NSArray *)dataArray success:(void (^)(id obj))success fail:(void (^)(NSError *error))fail {
// 分界線的標識符
NSString *TWITTERFON_FORM_BOUNDARY = @"IaX0GHJdM5gRIXY_S37dFzTjrYcygaI4lr8JjgHY_hUURrbjP8LbpzJ7KEQ2AbcY5yU3Jc";
// 根據 url 初始化 request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://桶名.oss-cn-beijing.aliyuncs.com"] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
// 分界線
NSString *MPboundary = [[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
// 結束符
NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
// http body 的字符串
NSMutableString *body = [[NSMutableString alloc] init];
// 參數的集合的全部key的集合
NSArray *keys= [parameterDict allKeys];
// 遍歷keys
for(int i = 0; i < [keys count]; i++) {
// 獲得當前key
NSString *key=[keys objectAtIndex:i];
// 添加分界線,換行
[body appendFormat:@"%@\r\n",MPboundary];
// 添加字段名稱,換2行
[body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
// 添加字段的值
[body appendFormat:@"%@\r\n",[parameterDict objectForKey:key]];
}
// 添加分界線,換行
[body appendFormat:@"%@\r\n",MPboundary];
// 聲明pic字段,文件名爲boris.png
[body appendFormat:@"%@", [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n",@"MyFilename"]];
// 聲明上傳文件的格式
[body appendFormat:@"Content-Type: image/png\r\n\r\n"];
NSString *paraString = [dataArray componentsJoinedByString:@","];
NSString *end=[[NSString alloc]initWithFormat:@"\r\n%@",endMPboundary];
// 聲明myRequestData,用來放入http body
NSMutableData *myRequestData = [NSMutableData data];
// 將body字符串轉化爲UTF8格式的二進制
[myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
// data加入
[myRequestData appendData:[paraString dataUsingEncoding:NSUTF8StringEncoding]];
// 加入結束符--AaB03x--
[myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
// 設置HTTPHeader中Content-Type的值
NSString *content = [[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
[request setValue:content forHTTPHeaderField:@"Content-Type"];
// 設置Content-Length
[request setValue:[NSString stringWithFormat:@"%d", (int)[myRequestData length]] forHTTPHeaderField:@"Content-Length"];
// 設置http body
[request setHTTPBody:myRequestData];
// http method
[request setHTTPMethod:@"POST"];
// 鏈接(NSURLSession)
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
} else {
if (success) {
success(@"");
}
}
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"body:%@", str);
}];
[dataTask resume];
}
複製代碼