首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Swift 3向web服务器发送参数和数据

使用Swift 3向web服务器发送参数和数据
EN

Stack Overflow用户
提问于 2016-11-17 04:19:29
回答 3查看 4.2K关注 0票数 0

我正在努力弄清楚如何将照片从iPhone发送到我的web服务器。

我还需要发送包含照片大小、文件名以及与参数数据相同的请求中有关照片的其他其他信息的参数。

下面的代码我认为是在正确的轨道上,但是我把参数数据params放在哪里呢?

代码语言:javascript
复制
        let params: Array<String> = [aI.filename, String(aI.size), String(aI.dateTime.year), String(aI.dateTime.month), String(aI.dateTime.day), String(aI.dateTime.hour), String(aI.dateTime.minute), String(aI.dateTime.second), String(aI.dateTime.millisecond)]


        var serverURL = URL(string: "http://192.168.0.23/upload.php");
        var req = NSMutableURLRequest(url: serverURL!, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: 60.0);
        //Set request to post
        req.httpMethod = "POST";

        //Set content type
        req.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type");


        let task = URLSession.sharedSession().dataTaskWithRequest(req){ data, response, error in
            if error != nil{
                print("Error -> \(error)")
                return
            }

            do {
                let result = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String:AnyObject]

                print("Result -> \(result)")

            } catch {
                print("Error -> \(error)")
            }
        }

        task.resume()
        return task
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-11-19 08:35:04

尽管有些答案把我推向了正确的方向,但它们仍然不适合我的项目,所以我继续在googling上搜索我在以下文章中所需要的内容:http://swiftdeveloperblog.com/image-upload-example/

我需要异步地和使用会话发出HTTP请求,问题中没有指定会话,因为问题只是关于如何在一个请求中发送两个参数以及数据。

当这样做时,它被称为Multipart Form Data

为了使其适用于我的应用程序,我不得不修改本文中的代码,所以我在下面分享我的Swift 3代码:

触发码

代码语言:javascript
复制
let params = [
            "filename"      : chunkOwner.filename                       ,
            "size"          : String(describing: chunkOwner.size)                   ,
            "year"          : String(chunkOwner.dateTime.year)          ,
            "month"         : String(chunkOwner.dateTime.month)         ,
            "day"           : String(chunkOwner.dateTime.day)           ,
            "hour"          : String(chunkOwner.dateTime.hour)          ,
            "minute"        : String(chunkOwner.dateTime.minute)        ,
            "second"        : String(chunkOwner.dateTime.second)        ,
            "millisecond"   : String(chunkOwner.dateTime.millisecond)   ,
        ]

uploadChunk(url: URL(string: "http://192.168.0.23/upload.php")!, data: photoData, params: params)

上传代码:

代码语言:javascript
复制
func uploadData(url: URL, data: Data!, params: [String: String])
    {
        let cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData;
        let request = NSMutableURLRequest(url: url, cachePolicy: cachePolicy, timeoutInterval: 6.0);
        request.httpMethod = "POST";

        let boundary = generateBoundaryString()

        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")


        if(data == nil)  { return; }

        request.httpBody = createBodyWithParameters(parameters: params, filePathKey: "file", data: data, boundary: boundary)



        //myActivityIndicator.startAnimating();

        let task = URLSession.shared.dataTask(with: request as URLRequest) {
            data, response, error in

            if error != nil {
                print("error=\(error)")
                return
            }

            // You can print out response object
            print("******* response = \(response)")

            // Print out reponse body
            let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            print("****** response data = \(responseString!)")

            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary

                print(json)



            }catch
            {
                //if you recieve an error saying that the data could not be uploaded,
                //make sure that the upload size is set to something higher than the size
                print(error)
            }


        }

        task.resume()

    }


    func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, data: Data!, boundary: String) -> Data {
        var body = Data();

        if parameters != nil {
            for (key, value) in parameters! {
                body.appendString(string: "--\(boundary)\r\n")
                body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
                body.appendString(string: "\(value)\r\n")
            }
        }

        let mimetype = "text/csv"

        body.appendString(string: "--\(boundary)\r\n")
        body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(parameters!["filename"]!)\"\r\n")
        body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")


        body.append(data)
        body.appendString(string: "\r\n")

        body.appendString(string: "--\(boundary)--\r\n")

        return body
    }




    func generateBoundaryString() -> String {
        return "Boundary-\(NSUUID().uuidString)"
    }

在类之外的.swift文件底部还包括以下代码:

代码语言:javascript
复制
extension Data {
    mutating func appendString(string: String) {
        append(string.data(using: .utf8)!)
    }
}

对于PHP上传脚本,我做了一些更改,现在如下所示:

代码语言:javascript
复制
<?php
    $target_dir = "/var/www/html/uploads";if(!file_exists($target_dir)){
        mkdir($target_dir, 0777, true);
    }

    $target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);
    echo count("size: ".$_FILES["file"]["tmp_name"]);


    if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)){

        echo json_encode([
            "Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
            "Status" => "OK",
        ]);

    } else {

        echo json_encode([
            "Message" => "Sorry, there was an error uploading your file.",
            "Status" => "Error",
        ]);

    }
?>

重要注:

如果将名为php.ini的服务器php文件配置为接受小于您要上载的数据的文件,则应用程序将无法上载数据。 例如:如果php.ini被配置为接受2MB,那么任何大于2MB的上传都将被忽略,您的应用程序将收到一个响应,说明出了问题。 要在php.ini中更改文件大小接受性,需要查找名为upload_max_filesizepost_max_size的变量,并将它们更改为系统所需的任何文件大小。

票数 1
EN

Stack Overflow用户

发布于 2016-11-17 04:25:17

您可以将它们放入httpBodyhttpBodyStream (通过使用NSInputStream)。

但是,不要忘记为服务器协议转换params (例如xml、json或具有自定义格式的二进制数据)。

对于您的内容类型(application/x-www-form-urlencoded),可以在维基百科中找到格式。

代码语言:javascript
复制
 keyName=value&keyName2=value2

键和值应该包含URLPathAllowedCharacterSet,要实现它,可以使用stringByAddingPercentEncodingWithAllowedCharacters

要将KeyValue字符串转换为NSData,可以使用方法dataUsingEncoding

票数 0
EN

Stack Overflow用户

发布于 2016-11-17 07:06:59

我将分享一种使用NSURLConnectionSwift3中发布数据的方式

您的URL

代码语言:javascript
复制
 var serverURL = URL(string: "http://192.168.0.23/upload.php")

您的参数如下所示,只需与服务器人员讨论需要传递数据的参数,然后将值分配给该参数,如下所示

代码语言:javascript
复制
serverparameter1 = \(value to post)& serverparameter2 = \(value to post2).......

和你的对立面,我像这样看一看

代码语言:javascript
复制
let params = "filename= \(aI.filename)&size = \(String(aI.size))& dateTimeYear =\(String(aI.dateTime.year))&dateTimeMonth =\(String(aI.dateTime.month))& dateTimeDay =\(String(aI.dateTime.day))&dateTimeHour =\(String(aI.dateTime.hour))&dateTimeMinute =\(String(aI.dateTime.minute))&dateTimeSecond =\(String(aI.dateTime.second))&dateTimeMilliSecond=\(String(aI.dateTime.millisecond))"

将照片数据转换为Base64String,如下所示

代码语言:javascript
复制
var base64String: NSString!
let myImage = UIImage(named:"image.png")
let imageData = UIImageJPEGRepresentation(myImage, 0.9)
base64String = imageData!.base64EncodedString(options: NSData.Base64EncodingOptions.endLineWithLineFeed) as NSString!
print(base64String)

然后作为stringParameter传递

代码语言:javascript
复制
&ImageDataStr = \(base64String)

最后的Url看起来就像

代码语言:javascript
复制
 \(serverURL)/\(params)

代码语言:javascript
复制
 \(serverURL)/Upload?\(params)

逐步请求

代码语言:javascript
复制
    var serverURL = URL(string: "http://192.168.0.23/upload.php")

    let params = "filename= \(aI.filename)&size = \(String(aI.size))& dateTimeYear =\(String(aI.dateTime.year))&dateTimeMonth =\(String(aI.dateTime.month))& dateTimeDay =\(String(aI.dateTime.day))&dateTimeHour =\(String(aI.dateTime.hour))&dateTimeMinute =\(String(aI.dateTime.minute))&dateTimeSecond =\(String(aI.dateTime.second))&dateTimeMilliSecond=\(String(aI.dateTime.millisecond))&photoDataStr = \(base64String)"

    var status:NSString = "\(serverURL)/Upload?\(params)" as NSString

    status = status.addingPercentEscapes(using: String.Encoding.utf8.rawValue)! as NSString


    let url = URL(string: status as String)!


    let request = URLRequest(url: url, cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 600)
    // need synchronous

在这里,您将得到responseData

代码语言:javascript
复制
      var response:URLResponse?
      var responseD:Data = try! NSURLConnection.sendSynchronousRequest(request, returning:&response)

最后,使该BinaryData可读

代码语言:javascript
复制
    // save to string - the result came from the Server call
    var serverResults:NSString = NSString(data: responseD, encoding: String.Encoding.utf8.rawValue)!

    print(serverResults)

例如,您的结果

代码语言:javascript
复制
if serverResults.range(of: "RESULT&gt;APPROVED").location != NSNotFound
    {
        return "Data posted"
    }
    else
    {
        return "Failed to post"
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40646652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档