下載影像到App中已不是問題,那麼上傳影像到伺服器呢?原本想要使用世界最知名的第三方套件AFNetworking,可是我怎麼嘗試都有錯誤,以為伺服器沒有做好,然而Android工程師和我們新的PM測試都可以成功,那麼一定是我這邊出了問題。
最後打算用原生的方式實作,寫法搞了一會兒,終於回傳成功!
先看一下做API的工程師所定義的格式:
### Upload user avatar [POST /images/user/avatar] + Request + Headers Authorization: Bearer {token} Content-Type: multipart/form-data;boundary=BoundaryName + Body --------BoundaryName Content-Disposition: form-data; name="image" Content-Type: application/octet-stream ... --------BoundaryName-- ... + Response 200 (application/json) { "status": { "code": 200, "message": "Success" } }
這裡我就嘗試使用原生的NSURLSession,程式碼乍看之下有點冗長,不過耐心研究一下就能知道邏輯原理。
有些部分可以任意命名,如boundary參數Happyboundary。
/** Theme: Upload Image to Server IDE: Xcode 7 Language: Objective C Date: 105/03/15 Author: HappyMan Blog: https://cg2010studio.wordpress.com/ */ - (void)uploadPhotoWithImage:(UIImage *)image success:(void (^)(NSDictionary *dictionary))successBlock fail:(void (^)(NSError *error))failBlock { // Build the request body NSString *boundary = @"Happyboundary"; NSMutableData *body = [NSMutableData data]; NSData *imageData = UIImageJPEGRepresentation(image, 0.7); if (imageData) { [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", @"image"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:imageData]; [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; } [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // Setup the session NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; sessionConfiguration.HTTPAdditionalHeaders = @{ @"Authorization" : [@"Bearer " stringByAppendingString:@"Happy Authorization"], @"Content-Type" : [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] }; // Create the session // We can use the delegate to track upload progress NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:nil delegateQueue:nil]; // Data uploading task. We could use NSURLSessionUploadTask instead of NSURLSessionDataTask if we needed to support uploads in the background NSURL *url = [NSURL URLWithString:[APIBaseDomain stringByAppendingString:@"images/user/avatar"]]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; request.HTTPBody = body; NSURLSessionDataTask *uploadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ NSError *err; NSDictionary *resultDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&err]; if (error == nil) { // Success NSLog(@"URL Session Task Succeeded: HTTP %ld", ((NSHTTPURLResponse*)response).statusCode); successBlock(resultDict); } else { // Failure NSLog(@"URL Session Task Failed: %@", [error localizedDescription]); failBlock(error); } }); }]; [uploadTask resume]; }
上述程式碼要記得改成自己的URL,Header和Body也要遵守伺服器的規定。
話說,是可以同時Upload檔案和Post參數呢!
從此就不用怕實作上傳檔案的功能囉~之後我也要自己來做Server和Database,做個全端工程師,如此很多idea就能輕鬆實現:D~
171114更新:
記得name要設定接影像檔的key喔~這裡是image。剛才卡在這兒許久,還問我們偉大的後台工程師,明明我之前也自己寫過XD~
隨意留個言吧:)~