下載影像到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~
隨意留個言吧:)~