9

I'm trying to upload video to my server. I select video from album but "fatal error: unexpectedly found nil while unwrapping an Optional value".

Please find the below code for more information.

let videoURL: String = NSBundle.mainBundle().pathForResource("IMG_2859", ofType: "MOV")!
// var videoData: NSData = NSData.dataWithContentsOfURL(NSURL.fileURLWithPath(videoURL))!
print(videoURL)
let data = NSData(contentsOfFile: videoURL)

print(data)

let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest()
print(session)
print(request)

request.URL =  NSURL(string:  "uploadvideo/uploadtoserver?user_email=\(candit_email)")
print(request.URL)

request.HTTPMethod = "POST"

let boundary = "------------------------8744f963ff229392"
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

let postData = NSMutableData()
postData.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

print("Upload Video File1")
postData.appendData("Content-Disposition: form-data; name=\"filedata\"; filename=\"MOV\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
 print("Upload Video File2")

postData.appendData("Content-Type: video/x-msvideo\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
 print("Upload Video File3")
postData.appendData(NSData(data: data!))
 print("Upload Video File4")
postData.appendData("\r\n--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
print("Upload Video File5")
request.HTTPBody = postData

print("Upload Video File6")

print(request.HTTPBody)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
    let error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
    do{
        if let jsonResult: NSDictionary! = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers) as? NSDictionary{


    }
    } catch let error as NSError {
    print(error.localizedDescription)
    }


})
 }

I had referred this below two links but no use for me.

1) Imageor-video-posting-to-server-in-swift
2) how-to-upload-video-to-server-from-iphone

Community
  • 1
  • 1
Manikandaprabu
  • 107
  • 1
  • 1
  • 5
  • Try using Alamofire, it is a lot easier. Refer to [this](https://github.com/Alamofire/Alamofire/issues/1004) if you need to pass parameters. – Nick Allen Feb 26 '16 at 08:20
  • Sorry for late replay .... I try Alamofire But show null error after this line let "videoURL: String = NSBundle.mainBundle().pathForResource("IMG_2859", ofType: "MOV")!" – Manikandaprabu Feb 26 '16 at 10:29
  • Where is this `IMG_2859` ? Your asset? If that is the case you should upload it using `UIImageJPEGRepresentation` as your assets will be packaged when compiled. Check the link I gave you above. – Nick Allen Feb 26 '16 at 10:49
  • IMG_2859 video in Albums -> Camera roll – Manikandaprabu Feb 26 '16 at 11:24
  • You can't access resources that not in your project this way. It makes no sense that you know that user's photo library happens to have the image you need. – Nick Allen Feb 26 '16 at 12:58
  • Hi Nick , then How to upload the photo library video to server ? The above code is correct way? func uploadVideoOne(candit_email:NSString{ } this is my function above code inside the parenthesis. – Manikandaprabu Feb 29 '16 at 09:38
  • Use UIImagePickerController and it's delegate to get movie's url. – Nick Allen Feb 29 '16 at 10:19
  • Hi Nick, I use the following code ,,and get movie's url func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { let urlvideo: NSURL = (info[UIImagePickerControllerMediaURL] as! NSURL) } how to call the "urlvideo" to above code – Manikandaprabu Feb 29 '16 at 10:56

2 Answers2

12

Update code to swift 4.2

Try this. It works for me.

Define a URL var first.

var videoPath: URL?

Then use UIImagePickerControllerDelegate to get file's info.

extension ViewController: UIImagePickerControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
            print(videoURL)
        }
        self.dismiss(animated: true, completion: nil)
    }
}

And this is upload event method:

// upload event
func uploadMedia(){
    if videoPath == nil {
        return
    }

    guard let url = URL(string: "server_path") else {
        return
    }
    var request = URLRequest(url: url)
    let boundary = "------------------------your_boundary"

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

    var movieData: Data?
    do {
        movieData = try Data(contentsOf: url, options: Data.ReadingOptions.alwaysMapped)
    } catch _ {
        movieData = nil
        return
    }

    var body = Data()

    // change file name whatever you want
    let filename = "upload.mov"
    let mimetype = "video/mov"

    body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Disposition:form-data; name=\"file\"; filename=\"\(filename)\"\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
    body.append(movieData!)
    request.httpBody = body

    let task = URLSession.shared.dataTask(with: request) { (data: Data?, reponse: URLResponse?, error: Error?) in
        if let `error` = error {
            print(error)
            return
        }
        if let `data` = data {
            print(String(data: data, encoding: String.Encoding.utf8))
        }
    }

    task.resume()
}
Argos
  • 121
  • 2
  • 7
3

Easy way will be to upload the file using Alamofire.

First install Alamofire using cocoapods

Include this in your pod file

pod 'Alamofire', '~> 4.0'

then go to terminal and change ddirectory to your project and enter

pod install

now

import Alamofire

Now you have get the video path you are trying to upload to server

 func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [String : Any])                       

 {   


   if let videoUrl = info[UIImagePickerControllerMediaURL] as? URL


  { 

    Alamofire.upload(multipartFormData: { (multipartFormData) in

            multipartFormData.append(videoUrl, withName: "Video")

        }, to:"http://yourserverpath.php")
        { (result) in
            switch result {
            case .success(let upload, _ , _):

                upload.uploadProgress(closure: { (progress) in

                    print("uploding")
                })

                upload.responseJSON { response in

                   print("done")

                }

            case .failure(let encodingError):
                print("failed")
                print(encodingError)

            }
        }



    self.dismiss(animated: true, completion: nil)
    }



}

And this is the php code

 <?php

 $imgname=$_FILES['video']['name'];
 $imgloc=$_FILES['video']['tmp_name'];
 if(move_uploaded_file($imgloc,"upload/".$imgname)){
    echo "success";
 }
 else{
echo "failed";
 }


 ?>
Subhojit Mandal
  • 450
  • 4
  • 13
  • is there a way to test the `.php` using something like: `curl --upload-file file.jpg --url http://remote_server_ip_addr/php_code_file.php`? – sAguinaga Feb 04 '18 at 19:56