Home > Net >  Can't generate live photo in iOS 15.1
Can't generate live photo in iOS 15.1

Time:11-05

Work well in iOS 15.0 but after upgrading to iOS 15.1, the codes can't get worked.

_ = PHLivePhoto.request(withResourceFileURLs: [pairedVideoURL, pairedImageURL], placeholderImage: nil, targetSize: CGSize.zero, contentMode: PHImageContentMode.aspectFit, resultHandler: { (livePhoto: PHLivePhoto?, info: [AnyHashable : Any]) -> Void in

    if let isDegraded = info[PHLivePhotoInfoIsDegradedKey] as? Bool, isDegraded {

        return

    }

    DispatchQueue.main.async {

        completion(livePhoto, (pairedImageURL, pairedVideoURL))

    }

})

Anyone can help?

CodePudding user response:

I had the same issue: PHLivePhoto.request is failing with PHPhotosErrorKey error 3302 which is PHPhotosErrorInvalidResource.

After doing some research, found out that from IOS 15.1, the "{MakerApple}" metadata field including the id of the Live Photo stop being written to the image file metadata and therefore the LivePhoto validation fails, as the identifier needs to be the same in both image and movie portion of the livePhoto.

After trying different things, found out that IOS is not writing the "{MakerApple}" metadata on JPEG images. It is only doing it on Apple's own file formats. (i.e. heic). (starting on IOS 15.1)

To solve the issue, encode your image portion as heic and the "{MakerApple}" metadata will be preserved. You can achieve this with something like this:

let assetIdentifier = UUID()

guard
    let destintation = CGImageDestinationCreateWithURL(imageURL as CFURL, UTType.heic.identifier as CFString, 1, nil),
    let data = staticUIImage!.heic,
    let imageSource = CGImageSourceCreateWithData(data as CFData, nil)
else {
    return
}

var metadata = CGImageSourceCopyProperties(imageSource, nil) as! [String : Any]
let makerNote = ["17" : assetIdentifier.uuidString]
metadata[String(kCGImagePropertyMakerAppleDictionary)] = makerNote
CGImageDestinationAddImageFromSource(destintation, imageSource, 0, metadata as CFDictionary)
CGImageDestinationFinalize(destintation)

To get the heic data I used the UIImage extension provided by Leo Dabus here

CodePudding user response:

    func addAssetID(_ assetIdentifier: String, toImage imageURL: URL, saveTo destinationURL: URL) -> URL? {
        
        let kFigAppleMakerNote_AssetIdentifier = "17"
        
        let image = UIImage(contentsOfFile: imageURL.path)
        let imageRef = image?.cgImage
        let imageMetadata = [kCGImagePropertyMakerAppleDictionary: [kFigAppleMakerNote_AssetIdentifier: assetIdentifier]]

        let cfUrl = destinationURL as CFURL

        let dest = CGImageDestinationCreateWithURL(cfUrl, kUTTypeJPEG, 1, nil)
        CGImageDestinationAddImage(dest!, imageRef!, imageMetadata as CFDictionary)
        _ = CGImageDestinationFinalize(dest!)
        
        return destinationURL
    }
  • Related