2017-01-23 157 views
2

我無法通過HTTPS POST請求將圖像上傳到Cloudinary託管,我想使用簡單的API方法而不是SDK。我在將圖像格式化爲字節數組緩衝區或Base64編碼時遇到問題。將圖像上傳到Cloudinary IOS

這裏是我的代碼:

UIImage *image = [UIImage imageNamed:@"image.png"]; 
NSData *imageData = UIImagePNGRepresentation(image); 
NSString *strImageData = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 

NSURL *url = [NSURL URLWithString:@"https://api.cloudinary.com/v1_1/MYSECTER/image/upload"]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
request.HTTPMethod = @"POST"; 
NSString *strRequest = [NSString stringWithFormat:@"file=%@&upload_preset=MYSECTER", strImageData]; 
request.HTTPBody = [strRequest dataUsingEncoding:NSUTF8StringEncoding]; 

[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 

    NSDictionary *recievedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; 

    NSLog(@"RECEIVED: %@", recievedData); 

}] resume]; 

不幸的是我收到以下來自服務器的回答:「不支持源URL ......」

我真的嘗試了很多其他的方法,但我可以」讓它工作。

更新:當我把URL鏈接放在'文件'參數一切正常。

回答

0

我找到解決方案,和它的作品非常好:

// image for sending 
UIImage *image = [UIImage imageNamed:@"image.png"]; 

// Dictionary that holds post parameters. You can set your post parameters that your server accepts or programmed to accept. 
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init]; 
[_params setObject:@"SECKET_PRESET" forKey:@"upload_preset"]; 

// the boundary string : a random string, that will not repeat in post data, to separate post data fields. 
NSString *BoundaryConstant = @"----------V2ymHFg03ehbqgZCaKO6jy"; 

// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ 
NSString* FileParamConstant = @"file"; 

// the server url to which the image (or the media) is uploaded. Use your server url here 
NSURL* requestURL = [NSURL URLWithString:@"https://api.cloudinary.com/v1_1/SECKET_KEY/image/upload"]; 

// create request 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; 
[request setHTTPShouldHandleCookies:NO]; 
[request setTimeoutInterval:30]; 
[request setHTTPMethod:@"POST"]; 

// set Content-Type in HTTP header 
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", BoundaryConstant]; 
[request setValue:contentType forHTTPHeaderField: @"Content-Type"]; 

// post body 
NSMutableData *body = [NSMutableData data]; 

// add params (all params are strings) 
for (NSString *param in _params) { 
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:[[NSString stringWithFormat:@"%@\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]]; 
} 

// add image data 
NSData *imageData = UIImagePNGRepresentation(image); 
if (imageData) { 
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:imageData]; 
    [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; 
} 

[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]]; 

// setting the body of the post to the reqeust 
[request setHTTPBody:body]; 

// set the content-length 
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[body length]]; 
[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 

// set URL 
[request setURL:requestURL]; 

[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 

    NSDictionary *recievedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; 

    NSLog(@"RECEIVED: %@", recievedData); 

}] resume]; 
0

我對Cloudinary API沒有任何經驗,但我希望這有幫助。我看了'Uploading with a direct call to the API'上的文檔。

我認爲你需要提供'文件'和'upload_preset'作爲POST參數(不要連接爲正文中的數據)。

UIImage *image = [UIImage imageNamed:@"image.png"]; 
NSData *imageData = UIImagePNGRepresentation(image); 
NSString *strImageData = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 

NSURL *url = [NSURL URLWithString:@"https://api.cloudinary.com/v1_1/MYSECTER/image/upload"]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
request.HTTPMethod = @"POST"; 

// Replace this: 

//NSString *strRequest = [NSString stringWithFormat:@"file=%@&upload_preset=MYSECTER", strImageData]; 
//request.HTTPBody = [strRequest dataUsingEncoding:NSUTF8StringEncoding]; 

// With this: 

NSString *imageDataStr = [[NSString alloc] initWithData:imageData encoding:NSUTF8StringEncoding]; 
[request setValue:imageDataStr forHTTPHeaderField:@"file"]; 
[request setValue:@"MYSECTER" forHTTPHeaderField:@"upload_preset"]; 


[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 

    NSDictionary *recievedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; 

    NSLog(@"RECEIVED: %@", recievedData); 

}] resume]; 
+0

嗨,感謝您的時間,但它不工作。 我收到錯誤信息:「缺少必需的參數 - 文件」; –

0

您可以使用Cloudinary的SDK,以執行上傳圖像的任務,因爲這裏解釋:http://cloudinary.com/blog/direct_upload_made_easy_from_browser_or_mobile_app_to_the_cloud

以下代碼示例顯示Objective-C for iOS中的直接未簽名上傳API調用...:

CLCloudinary *cloudinary = [[CLCloudinary alloc] init]; 
[cloudinary.config setValue:@"demo" forKey:@"cloud_name"]; 

NSString *imageFilePath = [[NSBundle mainBundle] pathForResource:@"logo" 
ofType:@"png"]; 

CLUploader* uploader = [[CLUploader alloc] init:cloudinary delegate:self]; 
[uploader unsignedUpload:imageFilePath uploadPreset:@"zcudy0uz" options:@{}]; 

下面的代碼示例顯示了一個更高級的示例:指定user_sample_image_1002的自定義公共ID,以便稍後訪問上傳的圖像以及分配標籤以簡化圖像管理。此外,我們還展示了一個構建動態URL的示例,該URL可以執行即時圖像處理:生成上傳圖像的150x100面部檢測縮略圖,以便嵌入到應用程序中。

NSData *imageData = [NSData dataWithContentsOfFile:imageFilePath]; 

[uploader unsignedUpload:imageData uploadPreset:@"zcudy0uz" options: 
[NSDictionary dictionaryWithObjectsAndKeys:@"user_sample_image_1002", 
@"public_id", @"tags", @"ios_upload", nil] withCompletion:^(NSDictionary 
*successResult, NSString *errorResult, NSInteger code, id context) { 

    if (successResult) { 

     NSString* publicId = [successResult valueForKey:@"public_id"]; 
     NSLog(@"Upload success. Public ID=%@, Full result=%@", publicId, 
     successResult); 
     CLTransformation *transformation = [CLTransformation transformation]; 
     [transformation setWidthWithInt: 150]; 
     [transformation setHeightWithInt: 100]; 
     [transformation setCrop: @"fill"]; 
     [transformation setGravity:@"face"]; 

     NSLog(@"Result: %@", [cloudinary url:publicId 
     options:@{@"transformation": 
     transformation, @"format": @"jpg"}]);     

    } else { 

     NSLog(@"Upload error: %@, %d", errorResult, code);    

     } 

} andProgress:^(NSInteger bytesWritten, NSInteger totalBytesWritten, 
    NSInteger totalBytesExpectedToWrite, id context) { 
    NSLog(@"Upload progress: %d/%d (+%d)", totalBytesWritten, 
    totalBytesExpectedToWrite, bytesWritten); 
}];