简体   繁体   English

使用rest rest呼叫上传图片-swift和php-编码问题

[英]upload image using post rest call - swift & php - encoding issue

I want to upload an image using its string representation to conform to my network function. 我想使用其字符串表示形式上传图像以符合我的网络功能。 code of the function (this one is working well) 该功能的代码(此代码运行良好)

func uploadItemPict(itemdata:String, itempicture:String, completion:     @escaping (AsyncResult<Any>)->())
{
    let myUrl = URL(string: urlAPIServer);
    var request = URLRequest(url:myUrl!)
    request.httpMethod = "POST"// Compose a query string
    var postString : String
    postString = "id="
    postString += itemdata
    postString += "&ip="
    postString += itempicture
    postString += "&cmd=uploadItemPicture"

    request.httpBody = postString.data(using: String.Encoding.utf8)

    let session = URLSession.shared
    let task = session.dataTask(with: request as URLRequest){
        (data, response, error) -> Void in
        if let error = error
        {
            completion(AsyncResult.Failure(error as NSError?))
        } else {
            //let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            //print("*********response data = \(String(describing: responseString))")
            //completion(AsyncResult.Success(responseString as Any))
            if let data = data {
                var json = try? JSONSerialization.jsonObject(with: data, options: [])
                if(json != nil) {
                    print(json!)
                    completion(AsyncResult.Success(json as Any))
                }
                else {
                    json = "{\"cmd\":\"uploadItemPict\",\"success\":\"false\",\"message\":\"wrong result: check if debug on on ws\"}"
                    print(json!)
                    let myerror = NSError(domain: "com.error.ws", code: 0, userInfo: [NSLocalizedDescriptionKey : "Wrong data from website"])
                    completion(AsyncResult.Failure(myerror as NSError?))
                }
            }
        }
    }
    task.resume()
}

here is the code to get the picture string: 这是获取图片字符串的代码:

    @IBAction func sendToto() {
    guard let url = Bundle.main.path(forResource: "toto", ofType: "jpg")
    else {
        // File Error
        print ("File reading error")
        return
    }
    let imageIn64String = UIImageJPEGRepresentation(UIImage(contentsOfFile: url)!, 0.7)?.base64EncodedString(options: .endLineWithLineFeed)
    if(isInternetAvailable()) {
        NSLog("internet available")
        uploadItemPict(itemdata: imageIn64String!, itempicture: "titi.jpg") {
            (result) in
            switch result
            {
            case .Success(let result):
                print("->success")
                break
            case .Failure(let error):
                print("->not a success")
                break
            }
        }
    }
}

I effectively get a string on the php side. 我实际上在php端得到了一个字符串。 I got an error with the method imagecreatefromstring so I decided to upload the toto.jpg on the server side and to get the local string, base64encoded to compare the 2 strings: 我在imagecreatefromstring方法中遇到了错误,因此我决定在服务器端上载toto.jpg并获取本地字符串base64encoded来比较这两个字符串:

$itemData = $this->getStringImage('id'); 
$itempicture = $this->getString('ip', 255); 
$itemDataLocal = file_get_contents("images/toto.jpg");
$itemDataLocal = base64_encode($itemDataLocal);
print($itemData);
print("<br>**************************************************<br>");
//print($itemDataGot);
//print("<br>**************************************************<br>");
print($itemDataLocal);
$itemDataLocal = base64_decode($itemDataLocal);
$image = imagecreatefromstring($itemDataLocal);
imagejpeg($image, "images/".$itempicture, 0.7);

When I compare the received string ($itemData) with the local ($itemDataLocal - with which, encoded and then decoded, I succeed in recreating the image), I got different string, and the received string from IOS is not recognized as a correct DATA string to create an image. 当我比较接收到的字符串($ itemData)与本地($ itemDataLocal-使用它进行编码然后解码后,我成功地重新创建了图像),我得到了不同的字符串,并且从IOS接收到的字符串未被识别为正确的字符串DATA字符串以创建图像。

Any Idea where I could do something wrong? 知道我可以在哪里做错什么吗?

Thanks 谢谢

EDIT: I though it was an issue of encoding in base64 in IOS, as the result between iOS and PHP is different. 编辑:我虽然是IOS中base64中编码的问题,因为iOS和PHP之间的结果是不同的。

As I had a doubt with the UIImageJPEGRepresentation, I thus tried to use something different: toto.jpg is the exact same file on iOS and on the server. 我对UIImageJPEGRepresentation表示怀疑,因此尝试使用其他方法:toto.jpg是iOS和服务器上的完全相同的文件。 On iOS, I tried the following: 在iOS上,我尝试了以下操作:

//Use image's path to create NSData
let url:NSURL = NSURL(string : "http://SERVER/app/images/toto.jpg")!
//Now use image to create into NSData format
let imageData:NSData = NSData.init(contentsOf: url as URL)!
let imageIn64String = imageData.base64EncodedString()
print(imageIn64String)

in this case, i have the same base64 string result as the one i had with php. 在这种情况下,我具有与php相同的base64字符串结果。 I thus suspect the issue might come from: UIImageJPEGRepresentation. 因此,我怀疑问题可能来自:UIImageJPEGRepresentation。

Any Idea? 任何想法? Thanks again 再次感谢

EDIT2: I got this working: EDIT2:我得到了这个工作:

guard let url1 = Bundle.main.path(forResource: "toto", ofType: "jpg")
    else {
        // File Error
        print ("File reading error")
        return
    }

    let imageData:NSData = NSData.init(contentsOfFile:url1)!
    let imageIn64String = imageData.base64EncodedString()

for the base64 encode string. 用于base64编码字符串。 This string contents some "+" symbols. 该字符串包含一些“ +”符号。 When I get the string on the php side, the "+" disappeared, and thus the image can't be recreated. 当我在php端获取字符串时,“ +”消失了,因此无法重新创建图像。 I'm using this to get the string: 我正在使用它来获取字符串:

$string = $_POST[$name];

I checked the httprequest to make sure I send the string including the "+"s: 我检查了httprequest以确保我发送了包含“ +”的字符串:

request.httpBody = postString.data(using: String.Encoding.utf8)
NSLog(String(data: request.httpBody!, encoding: String.Encoding.utf8)!)

I can see the "+"s in the request. 我可以在请求中看到“ +”号。

What am I doing wrong? 我究竟做错了什么?

got it working by escaping the + as it appear in the params (as per the answer provided by Rob: https://stackoverflow.com/a/24888789/2122773 ) 通过转义参数中出现的+使其工作(根据Rob提供的答案: https : //stackoverflow.com/a/24888789/2122773

guard let url1 = Bundle.main.path(forResource: "toto", ofType: "jpg")
else {
    // File Error
    print ("File reading error")
    return
}

let imageData:NSData = NSData.init(contentsOfFile:url1)!
let imageIn64String = imageData.base64EncodedString().replacingOccurrences(of: "+", with: "%2B")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM