Just My Life & My Work

下載影像到App中已不是問題,那麼上傳影像到伺服器呢?原本想要使用世界最知名的第三方套件AFNetworking,可是我怎麼嘗試都有錯誤,以為伺服器沒有做好,然而Android工程師我們新的PM測試都可以成功,那麼一定是我這邊出了問題。

marry me cake.jpg

最後打算用原生的方式實作,寫法搞了一會兒,終於回傳成功!

先看一下做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參數呢!

從此就不用怕實作上傳檔案的功能囉~之後我也要自己來做ServerDatabase,做個全端工程師,如此很多idea就能輕鬆實現:D~

171114更新:

記得name要設定接影像檔的key喔~這裡是image。剛才卡在這兒許久,還問我們偉大的後台工程師,明明我之前也自己寫過XD~

參考:Send POST request using NSURLSession

廣告

隨意留個言吧:)~

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

標籤雲

%d 位部落客按了讚: