iOS 8 Photos framework. Access photo metadata

后端 未结 6 1196
臣服心动
臣服心动 2020-12-07 11:33

I\'m looking at replacing ALAssetsLibrary with Photos framework in my app.

I can retrieve photos, collections, and asset sources just fine (even write t

6条回答
  •  再見小時候
    2020-12-07 12:33

    You can modify the PHAsset (e.g. adding location metadata) using Photos Framework and the UIImagePickerControllerDelegate method. No overhead from third party libraries, no duplicate photos created. Works for iOS 8.0+

    In the didFinishPickingMediaWithInfo delegate method, call UIImageWriteToSavedPhotosAlbum to first save the image. This will also create the PHAsset whose EXIF GPS data we will modify:

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    
        if let myImage = info[UIImagePickerControllerOriginalImage] as? UIImage  {
    
            UIImageWriteToSavedPhotosAlbum(myImage, self, Selector("image:didFinishSavingWithError:contextInfo:"), nil)
        }    
    }
    

    The completion selector function will run after the save completes or fails with error. In the callback, fetch the newly created PHAsset. Then, create a PHAssetChangeRequest to modify the location metadata.

    func image(image: UIImage, didFinishSavingWithError: NSErrorPointer, contextInfo:UnsafePointer)       {
    
        if (didFinishSavingWithError != nil) {
            print("Error saving photo: \(didFinishSavingWithError)")
        } else {
            print("Successfully saved photo, will make request to update asset metadata")
    
            // fetch the most recent image asset:
            let fetchOptions = PHFetchOptions()
            fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
            let fetchResult = PHAsset.fetchAssetsWithMediaType(PHAssetMediaType.Image, options: fetchOptions)
    
            // get the asset we want to modify from results:
            let lastImageAsset = fetchResult.lastObject as! PHAsset
    
            // create CLLocation from lat/long coords:
            // (could fetch from LocationManager if needed)
            let coordinate = CLLocationCoordinate2DMake(myLatitude, myLongitude)
            let nowDate = NSDate()
            // I add some defaults for time/altitude/accuracies:
            let myLocation = CLLocation(coordinate: coordinate, altitude: 0.0, horizontalAccuracy: 1.0, verticalAccuracy: 1.0, timestamp: nowDate)
    
            // make change request:
            PHPhotoLibrary.sharedPhotoLibrary().performChanges({
    
                // modify existing asset:
                let assetChangeRequest = PHAssetChangeRequest(forAsset: lastImageAsset)
                assetChangeRequest.location = myLocation
    
                }, completionHandler: {
                    (success:Bool, error:NSError?) -> Void in
    
                    if (success) {
                        print("Succesfully saved metadata to asset")
                        print("location metadata = \(myLocation)")
                    } else {
                        print("Failed to save metadata to asset with error: \(error!)")
    }
    

提交回复
热议问题