2016-11-17 48 views
0

我想弄清楚如何從iPhone發送照片到我的網絡服務器。發送參數和數據到網絡服務器與斯威夫特3

我還需要發送參數,其中包含照片的大小,它的文件名和其他與照片相關的附加信息與參數數據相同。

下面的代碼是在正確的軌道,我認爲,但我在哪裏把params稱爲參數數據:

 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 

回答

1

Allthough一些答案,把我推在正確的方向,他們仍然不適合我的項目,所以我繼續在谷歌上搜索我設法找到我需要在下面的文章到底是什麼:http://swiftdeveloperblog.com/image-upload-example/

我需要異步發出HTTP請求並使用會話, 我沒有在問題中指定,因爲問題僅僅是關於如何在單個請求中同時發送幾個參數和數據。

這樣做時稱爲Multipart Form Data

我不得不從文章修改代碼一點點,使之成爲我的應用程序工作, 所以我分享我的斯威夫特3下面的代碼:

觸發代碼

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) 

上傳代碼:

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)" 
    } 

還包括在你底部下面的代碼文件類之外:

extension Data { 
    mutating func appendString(string: String) { 
     append(string.data(using: .utf8)!) 
    } 
} 

而對於PHP上傳腳本我做了一些改變,現在看起來是這樣的:

<?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文件被稱爲 php.ini被配置爲接受比你的數據更小的文件試圖上傳的。

例如:如果php.ini配置爲接受2 MB,那麼任何 上傳大於2 MB將被忽略,你的應用程序將收到 迴應說,出事了。

要更改php.ini文件大小接受你需要尋找 變量稱爲upload_max_filesizepost_max_size和改變那些無論文件大小 您的系統要求。

0

你可以把它們httpBodyhttpBodyStream(通過使用NSInputStream)

但不要忘記爲服務器協議轉換參數(例如xml,json或具有自定義格式的二進制數據)。
爲您的內容類型(應用程序/ x-WWW的形式,進行了urlencoded),你可以在wikipedia找到格式:

keyName=value&keyName2=value2 

的鍵和值應該包含URLPathAllowedCharacterSet,實現它,你可以使用stringByAddingPercentEncodingWithAllowedCharacters
要將KeyValue字符串轉換爲NSData,可以使用方法dataUsingEncoding

0

我分享你的一種方式使用NSURLConnection發佈數據的Swift3

你的URL

var serverURL = URL(string: "http://192.168.0.23/upload.php") 

你的參數是這樣的,只是服務器的人討論哪些參數需要傳遞的數據那麼你的價值分配給參數如下圖所示

serverparameter1 = \(value to post)& serverparameter2 = \(value to post2)....... 

有了您的PARAMS我不喜歡這樣看看

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像下面

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

&ImageDataStr = \(base64String) 

那麼最後的網址看起來像

\(serverURL)/\(params) 

OR

\(serverURL)/Upload?\(params) 

步步要求

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

 var response:URLResponse? 
     var responseD:Data = try! NSURLConnection.sendSynchronousRequest(request, returning:&response) 

最後做出BinaryData爲可讀

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

    print(serverResults) 

例如:閣下的結果

if serverResults.range(of: "RESULT&gt;APPROVED").location != NSNotFound 
    { 
     return "Data posted" 
    } 
    else 
    { 
     return "Failed to post" 
    } 
+0

但哪一個照片數據?我可以一步一步看到有參數,但最終請求中的照片數據在哪裏? 此外,你的榜樣是不是異步的,並且不使用會話,這是不是蘋果了建議。 – vaid

+0

請參閱編輯。發送數據的 一種方式是 - 將您的照片數據,以Base64String,並將其發送 – Sanju

+0

謝謝你的答案,但我設法找到適合我的問題完全別處的信息,我分享了我的結論,並寫了我自己的答案。 – vaid