2017-06-14 18 views
0

画像をサーバーに送信できません。 サーバーに画像をアップロードすることはできません。私はSwiftアプリを作っていて、自分のアプリでDjangoサーバーに画像をアップロードするシステムを作りたいと思っています。さて、PhotoControllerは(それはシステムのためである)画像をサーバーに送信できません

import Foundation 
import MobileCoreServices 
import UIKit 
class PhotoController:UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate{ 

    @IBOutlet weak var myActivityIndicator: UIActivityIndicatorView! 
    @IBOutlet weak var label: UILabel! 
    @IBOutlet weak var myImageView: UIImageView! 
    private var imagePicker:UIImagePickerController! 

    @IBAction func uploadButtonTapped(_ sender: Any) { 
     myImageUploadRequest() 
    } 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     label.adjustsFontSizeToFitWidth = true 
     label.minimumScaleFactor = 0.5 
     label.text = "Tap the PhotoSelect or Camera to upload a picture" 
    } 

    @IBAction func PhotoSelect(_ sender: Any) { 
     let myPickerController = UIImagePickerController() 
     myPickerController.delegate = self; 
     myPickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary 

     self.present(myPickerController, animated: true, completion: nil) 

    } 

    @IBAction func Camera(_ sender: Any) { 
     let sourceType:UIImagePickerControllerSourceType = UIImagePickerControllerSourceType.camera 
     // カメラが利用可能かチェック 
     if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera){ 
      // インスタンスの作成 
      let cameraPicker = UIImagePickerController() 
      cameraPicker.sourceType = sourceType 
      cameraPicker.delegate = self 
      self.present(cameraPicker, animated: true, completion: nil) 

     } 
     else{ 
      label.text = "error" 
     } 
    } 
    // 撮影が完了時した時に呼ばれる 
    func imagePickerController(_ imagePicker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 

     if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage { 
      myImageView.contentMode = .scaleAspectFit 
      myImageView.image = pickedImage 

     } 

     //閉じる処理 
     imagePicker.dismiss(animated: true, completion: nil) 
     label.text = "Tap the Send to save a picture" 

    } 

    // 撮影がキャンセルされた時に呼ばれる 
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 
     picker.dismiss(animated: true, completion: nil) 
     label.text = "Canceled" 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func myImageUploadRequest() 
    { 

     let myUrl = NSURL(string: "http://localhost:8000/admin/accounts/post/"); 
     let request = NSMutableURLRequest(url:myUrl! as URL); 
     request.httpMethod = "POST"; 
     //ユーザーごとに割り振りたい 
     let param = [ 
      "firstName" : "Sergey", 
      "lastName" : "Kargopolov", 
      "userId" : "9" 
     ] 

     let boundary = generateBoundaryString() 

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


     let imageData = UIImageJPEGRepresentation(myImageView.image!, 1) 

     if(imageData==nil) { return; } 

     request.httpBody = createBodyWithParameters(parameters: param, filePathKey: "file", imageDataKey: imageData! as NSData, boundary: boundary) as Data 


     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 

       DispatchQueue.main.async { 
        self.myActivityIndicator.stopAnimating() 
        self.myImageView.image = nil; 
       } 

      }catch 
      { 
       print(error) 
      } 

     } 

     task.resume() 
    } 
    func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData { 
     let body = NSMutableData(); 

     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 filename = "user-profile.jpg" 
     let mimetype = "image/jpg" 

     body.appendString(string: "--\(boundary)\r\n") 
     body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n") 
     body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n") 
     body.append(imageDataKey as Data) 
     body.appendString(string: "\r\n") 
     body.appendString(string: "--\(boundary)--\r\n") 

     return body 
    } 

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

} 
extension NSMutableData { 

    func appendString(string: String) { 
     let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true) 
     append(data!) 
    } 
} 

このURLはmyUrl = NSURL(文字列: "http://localhost:8000/admin/accounts/post/")させています。私のサーバーのイメージアップロードURLです。トレースバックが

2017-06-14 23:04:50.480209 Kenshin_Swift[262:8094] [Generic] Creating an image format with an unknown type is an error 
2017-06-14 23:04:52.660264 Kenshin_Swift[262:8267] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file. 
error=Optional(Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSUnderlyingError=0x174456e90 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "(null)"}, NSErrorFailingURLStringKey=http://localhost:8000/admin/accounts/post/, NSErrorFailingURLKey=http://localhost:8000/admin/accounts/post/, NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.}) 

私のInfo.plistは

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
<dict> 
    <key>NSAppTransportSecurity</key> 
    <dict> 
    <key>NSExceptionDomains</key> 
    <dict> 
    <key>example.com</key> 
    <dict> 
     <!--Include to allow subdomains--> 
     <key>NSIncludesSubdomains</key> 
     <true/> 
     <!--Include to allow HTTP requests--> 
     <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> 
     <true/> 
     <!--Include to specify minimum TLS version--> 
     <key>NSTemporaryExceptionMinimumTLSVersion</key> 
     <string>TLSv1.1</string> 
    </dict> 
    </dict> 
    </dict> 
    <key>CFBundleSignature</key> 
    <string></string> 
    <key>CFBundleGetInfoString</key> 
    <string></string> 
    <key>CFBundleDisplayName</key> 
    <string></string> 
    <key>NSPhotoLibraryUsageDescription</key> 
    <string>for photo library</string> 
    <key>NSCameraUsageDescription</key> 
    <string>for camera</string> 
    <key>LSApplicationCategoryType</key> 
    <string></string> 
    <key>CFBundleDevelopmentRegion</key> 
    <string>en</string> 
    <key>CFBundleExecutable</key> 
    <string>$(EXECUTABLE_NAME)</string> 
    <key>CFBundleIdentifier</key> 
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 
    <key>CFBundleInfoDictionaryVersion</key> 
    <string>6.0</string> 
    <key>CFBundleName</key> 
    <string>$(PRODUCT_NAME)</string> 
    <key>CFBundlePackageType</key> 
    <string>APPL</string> 
    <key>CFBundleShortVersionString</key> 
    <string>1.0</string> 
    <key>CFBundleVersion</key> 
    <string>1</string> 
    <key>LSRequiresIPhoneOS</key> 
    <true/> 
    <key>NSHumanReadableCopyright</key> 
    <string></string> 
    <key>UILaunchStoryboardName</key> 
    <string>LaunchScreen</string> 
    <key>UIMainStoryboardFile</key> 
    <string>Main</string> 
    <key>UIRequiredDeviceCapabilities</key> 
    <array> 
     <string>armv7</string> 
    </array> 
    <key>UISupportedInterfaceOrientations</key> 
    <array> 
     <string>UIInterfaceOrientationPortrait</string> 
     <string>UIInterfaceOrientationLandscapeLeft</string> 
     <string>UIInterfaceOrientationLandscapeRight</string> 
    </array> 
    <key>UISupportedInterfaceOrientations~ipad</key> 
    <array> 
     <string>UIInterfaceOrientationPortrait</string> 
     <string>UIInterfaceOrientationPortraitUpsideDown</string> 
     <string>UIInterfaceOrientationLandscapeLeft</string> 
     <string>UIInterfaceOrientationLandscapeRight</string> 
    </array> 
</dict> 
</plist> 

ですトレースバックは私のInfo.plistが間違っている私に言ったが、私は間違っているのか分かりません。 は確かに、私は、Info.plistのために

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSExceptionDomains</key> 
    <dict> 
    <key>example.com</key> 
    <dict> 
     <!--Include to allow subdomains--> 
     <key>NSIncludesSubdomains</key> 
     <true/> 
     <!--Include to allow HTTP requests--> 
     <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> 
     <true/> 
     <!--Include to specify minimum TLS version--> 
     <key>NSTemporaryExceptionMinimumTLSVersion</key> 
     <string>TLSv1.1</string> 
    </dict> 
    </dict> 
</dict> 

を追加しましたので、画像は右、これはInfo.plistのエラーだと思ったが、このエラーは私のサーバーにありますか?どのように私のserver.Iに送信することができない理由を私は理解できません私はこれを修正できますか?あなたのInfo.plistで

+1

あなたはサーバ(django)コードのいくつかのスニペットをdjangoコードの問題として投稿できますか? –

答えて

0

この

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSExceptionDomains</key> 
    <dict> 
    <key>example.com</key> 
    <dict> 
     <!--Include to allow subdomains--> 
     <key>NSIncludesSubdomains</key> 
     <true/> 
     <!--Include to allow HTTP requests--> 
     <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> 
     <true/> 
     <!--Include to specify minimum TLS version--> 
     <key>NSTemporaryExceptionMinimumTLSVersion</key> 
     <string>TLSv1.1</string> 
    </dict> 
    </dict> 
</dict> 

この

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <true/> 
</dict> 
0

問題に置き換えることは、あなたが(ドメイン名を介してホストに接続する場合には、HTTPSプロトコルを使用する必要があるということですアップルの要件)。 httpsを実装できない場合は、http経由で接続できますが、IPアドレスを使用する必要があります。

関連する問題