简体   繁体   中英

how do I get NSURL for an image froom UIImagePickerController? for upload to Firebase

So there have been a few other threads started because people have trouble with this. like this one: Obtain NSURL from UIImagePickerController and this one: Firebase storage upload works in Simulator but not on iPhone

I am trying to follow this tutorial: https://firebase.google.com/docs/storage/ios/upload-files#upload_from_a_local_file

My video uploads work, just not images.

My video code is straightforward:

if mediaType.isEqualToString(kUTTypeMovie as String) {
        let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL

        fileToUploadURL = videoURL!
    }

but my image code doesn't work. this is what i have ended up with:

        let imageUrl = info["UIImagePickerControllerReferenceURL"] as? NSURL

        let assets = PHAsset.fetchAssetsWithALAssetURLs([imageUrl!], options: nil)
        let asset = assets.firstObject
        asset?.requestContentEditingInputWithOptions(nil, completionHandler: { (contentEditingInput, info) in
            let imageFile = contentEditingInput?.fullSizeImageURL
            // now call putFile with imageFile instead of imageUrl
            self.fileToUploadURL = imageFile
        })

seems like no matter what I do I'm getting an error. this is my current error

2016-06-25 12:45:23.695 Chain[4187:1957121] Body file is unreachable: /var/mobile/Media/DCIM/100APPLE/IMG_0027.JPG
 Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_0027.JPG”       couldn’t be opened because you don’t have permission to view it."

CONSOLE LOG

2016-06-25 12:47:59.108 Chain[4187:1957121] Body file is unreachable: /var/mobile/Media/DCIM/100APPLE/IMG_0027.JPG Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_0027.JPG” couldn't be opened because you don't have permission to view it." UserInfo={NSURL=file:///var/mobile/Media/DCIM/100APPLE/IMG_0027.JPG, NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0027.JPG, NSUnderlyingError=0x18b7ad40 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}} 2016-06-25 12:48:02.969 Chain[4187:1957659] plugin com.swiftkey.SwiftKeyApp.Keyboard invalidated Optional(["public.image", "public.movie"]) info: ["UIImagePickerControllerOriginalImage": size {1836, 1454} orientation 0 scale 1.000000, "UIImagePickerControllerReferenceURL": assets-library://asset/asset.JPG?id=5FE3480C-0A3E-42B2-B83B-93D0F321A3B2&ext=JPG, "UIImagePickerControllerMediaType": public.image, "UIImagePickerControllerCropRect": NSRect: {{0, 0}, {1836, 1452}}, "UIImagePickerControllerEditedImage": size {638, 504} orientation 0 scale 1.000000] fileToUploadURL: file:///var/mobile/Media/DCIM/100APPLE/IMG_0027.JPG Optional(["public.image", "public.movie"]) 2016-06-25 13:01:58.845 Chain[4187:1958957] plugin com.swiftkey.SwiftKeyApp.Keyboard invalidated info: ["UII magePickerControllerOriginalImage": size {1836, 1454} orientation 0 scale 1.000000, "UIImagePickerControllerReferenceURL": assets-library://asset/asset.JPG?id=CFF5692E-2B93-407D-A9E4-48AC1BEDCAF2&ext=JPG, "UIImagePickerControllerMediaType": public.image, "UIImagePickerControllerCropRect": NSRect: {{0, 0}, {1836, 1452}}, "UIImagePickerControllerEditedImage": size {638, 504} orientation 0 scale 1.000000] fileToUploadURL: nil

2016-06-25 13:04:05.136 Chain[4187:1957121] _BSMachError: (os/kern) invalid capability (20) 2016-06-25 13:04:05.138 Chain[4187:1959394] _BSMachError: (os/kern) invalid name (15) 2016-06-25 13:04:05.146 Chain[4187:1959394] plugin com.swiftkey.SwiftKeyApp.Keyboard invalidated 2016-06-25 13:04:05.220 Chain[4187:1957188] CFNetwork SSLHandshake failed (-9806) 2016-06-25 13:04:05.661 Chain[4187:1957121] Body file is unreachable: /var/mobile/Media/DCIM/100APPLE/IMG_0015.JPG Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_0015.JPG” couldn't be opened because you don't have permission to view it." UserInfo={NSURL=file:///var/mobile/Media/DCIM/100APPLE/IMG_0015.JPG, NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0015.JPG, NSUnderlyingError=0x18bd4330 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

edit: this is my didFinishPickingMedia:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {


    let mediaType = info[UIImagePickerControllerMediaType] as! NSString

    print ("info: \(info)")

    if mediaType.isEqualToString(kUTTypeImage as String) {
        var newImage: UIImage

        if let possibleImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
            newImage = possibleImage
        }
        else if let possibleImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
            newImage = possibleImage
        }

        else {
            return
        }

      /// CAN NOT GET NSURL working, NEED TO USE NSDATA
        if let jpegData:NSData = UIImageJPEGRepresentation(newImage, 80) {
            currentMediaTypeToUpload = "img"
            fileToUploadDATA = jpegData
        }

    }


    else if mediaType.isEqualToString(kUTTypeMovie as String) {
        let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL

        fileToUploadURL = videoURL!
        currentMediaTypeToUpload = "vid"
    }

The solution is here: how do I get NSURL for an image froom UIImagePickerController? for upload to Firebase

Applied to our problem:

if  let referenceUrl = info[UIImagePickerControllerReferenceURL] {

        ////
        let assetURL = NSURL(string: String(referenceUrl))
        let assets = PHAsset.fetchAssetsWithALAssetURLs([assetURL!], options: nil)
        let asset: PHAsset = assets.firstObject as! PHAsset
        let manager = PHImageManager.defaultManager()
        let requestSize =   PHImageManagerMaximumSize
        manager.requestImageForAsset(asset, targetSize: requestSize, contentMode: .AspectFit, options: nil, resultHandler: {(result, info)->Void in
            // Result is a UIImage
            // Either upload the UIImage directly or write it to a file
            let imageData = UIImageJPEGRepresentation(result!, 0.8)
            let imagePath = FIRAuth.auth()!.currentUser!.uid + "/\(Int(NSDate.timeIntervalSinceReferenceDate() * 1000)).jpg"
            print ("filePath: ", imagePath)
            let metadata = FIRStorageMetadata()
            metadata.contentType = "image/jpeg"
            self.storageRef.child(imagePath)
                .putData(imageData!, metadata: metadata) { (metadata, error) in
                    if let error = error {
                        print("Error uploading: \(error.description)")
                        return
                    }
                    self.sendMessage([Constants.MessageFields.imageUrl: self.storageRef.child((metadata?.path)!).description])
                    print("Succeded")
            }

        })
    }

With this solution I could upload my files to firebase.

NSURL s returned from UIImagePickerController s have the scheme assets-library:// , which isn't directly accessible by file system URL libs (ours included). You'll have to go through the Photos framework to retrieve content, and either write that data to a separate NSURL or upload it in memory.

  let assetURL = NSURL(string: "assets-library://path/to/content")
  let assets = PHAsset.fetchAssetsWithALAssetURLs([assetURL!], options: nil)
  let asset: PHAsset = assets.firstObject as! PHAsset

  let manager = PHImageManager.defaultManager()
  manager.requestImageForAsset(asset, targetSize: CGSize(width: 100.0, height: 100.0), contentMode: .AspectFit, options: nil, resultHandler: {(result, info)->Void in
    // Result is a UIImage
    // Either upload the UIImage directly or write it to a file
  })

This sample code taken from here , as part of our I/O talk Zero to App: Develop with Firebase .

I'm not sure how exactly you're trying to get the image from your UIImagePickerController instance, but you can implement the delegate and get the UIImage instance and then upload it to FirbaseStorage using the 'in-memory' method:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
    guard let imageData = UIImageJPEGRepresentation(image, 1.0) else { return }

    let storageRef = FIRStorage.storage().referenceForURL("gs://project-id.appspot.com")
    imagesRef.putData(imageData, metadata: nil) { metadata, error in
        ...
    }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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