将图像和文本值上传到服务器

时间:2015-10-01 14:28:59

标签: ios image swift multipartform-data nsurlsession

我尝试使用多部分创建一个带有图像和其他值的新对象,但我无法使其工作。

这是我在没有上传图片的情况下使用的代码(可行):

let request = NSMutableURLRequest(URL: NSURL(string: self.submitLink)!)
    let session = NSURLSession.sharedSession()
    let params = [
        "article": [
            "name" : name,
            "description" : fullDescription.text!,
            "subdescription" : sDescription,
            "category_id" : categoriesArray[self.categoryPicked]["id"] as! Int,
            "location_id" : locationsArray[self.locationPicked]["id"] as! Int,
            "Xcoordinate" : self.lat,
            "Ycoordinate" : self.lng,
            "user_id" : User.sharedInstance.userId,
            "article_images_attributes[][image]" : ""
        ]
    ]

    request.HTTPBody = try? NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions())
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.HTTPMethod = "POST"

    let task = session.dataTaskWithRequest(request, completionHandler: { data, response, error -> Void in
        print("article created.")
    })

    task.resume()

这是我目前正在使用的代码(不工作):

let params = [
        "article[name]" : name,
        "article[description]" : fullDescription.text!,
        "article[subdescription]" : sDescription,
        "article[category_id]" : categoriesArray[self.categoryPicked]["id"] as! Int,
        "article[location_id]" : locationsArray[self.locationPicked]["id"] as! Int,
        "article[Xcoordinate]" : self.lat,
        "article[Ycoordinate]" : self.lng,
        "article[user_id]" : User.sharedInstance.userId
    ]

    let boundaryConstant = "----------V2ymHFg03ehbqgZCaKO6jy"
    let fileParamConstant = "article[article_images_attributes][][image]"
    let session = NSURLSession.sharedSession()
    let request = NSMutableURLRequest(URL: NSURL(string: self.submitLink)!)

    request.HTTPMethod = "POST"

    let contentType = "multipart/form-data; boundary=\(boundaryConstant)"

    request.setValue(contentType, forHTTPHeaderField: "Content-Type")

    let body = NSMutableData()
    for param in params {
        print(param)
        body.appendData("--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Content-Disposition: form-data; \(param.key)=\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("\(param.value)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    }

    let imageData = UIImageJPEGRepresentation(self.photoArray[0], 1)
    if imageData != nil {
        body.appendData("--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Content-Disposition: form-data; name=\(fileParamConstant); filename=\"image.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData("Content-Type: application/octet-stream\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        body.appendData(imageData!)
        body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    }
    body.appendData("--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

    request.HTTPBody = body

    let task = session.dataTaskWithRequest(request, completionHandler: { data, response, error -> Void in
        print(request)
        print(data)
    })

    task.resume()

每当我尝试提交表单时,服务器都会回复:

  

NoMethodError(未定义方法`name' for nil:NilClass)

所以我认为我定义params的方式有问题?有人可以向我解释一下这个问题,所以我知道我做错了吗?

1 个答案:

答案 0 :(得分:0)

您的图片似乎使用了错误的Content-Typename可能不正确。

尝试使用以下方法设置图片:

NSMutableData *body = [NSMutableData data];
double compressionRatio=0.7;
NSData* imageData = UIImageJPEGRepresentation((UIImage*)dataParam, compressionRatio);

[self utfAppendBody:body data:[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\".jpg\"\r\n", paramName]];

[self utfAppendBody:body data:@"Content-Type: image/jpeg\r\n\r\n"];
[body appendData:imageData];

使用此辅助函数:

- (void)utfAppendBody:(NSMutableData *)body data:(NSString *)data {
    [body appendData:[data dataUsingEncoding:NSUTF8StringEncoding]];
}