How to properly send an image to CloudKit as CKAsset?

后端 未结 3 1873
你的背包
你的背包 2020-12-10 06:00

I have an image (UIImage and it\'s url too) and I\'m trying to send it to CloudKit as a CKAsset but I\'m having this error: Terminating app due to uncaught exception \

3条回答
  •  春和景丽
    2020-12-10 06:43

    I did something a tad different: I made a class that you can use in multiple places, and thanks to the fact that Swift has reinitialization that works (unlike C++), it cleans up after itself:

    //
    //  ImageAsset.swift
    //
    
    import CloudKit
    import UIKit
    
    class ImageAsset {
    
        let image:UIImage
    
        var url:NSURL?
    
        var asset:CKAsset? {
            get {
                let data = UIImagePNGRepresentation(self.image)
                self.url = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(NSUUID().UUIDString+".dat")
                if let url = self.url {
                    do {
                        try data!.writeToURL(url, options: [])
                    } catch let e as NSError {
                        print("Error! \(e)")
                    }
                    return CKAsset(fileURL: url)
                }
                return nil
            }
        }
    
        init(image:UIImage){
            self.image = image
        }
    
        deinit {
            if let url = self.url {
                do {
                    try NSFileManager.defaultManager().removeItemAtURL(url) }
                catch let e {
                    print("Error deleting temp file: \(e)")
                }
            }
        }
    
    
    }
    

    Here's a unit test that exercises it (presumes there is an image named stopwatch in the test target):

    //
    //  ImageExtensionTests.swift
    //
    
    import CloudKit
    import XCTest
    @testable import BudgetImpactEstimator
    
    class ImageExtensionTests: XCTestCase {
    
        let testImageName = "stopwatch" // provide the name of an image in test bundle
        override func setUp() {
            super.setUp()
            // Put setup code here. This method is called before the invocation of each test method in the class.
        }
    
        override func tearDown() {
            // Put teardown code here. This method is called after the invocation of each test method in the class.
            super.tearDown()
        }
    
        func testConvertingImageToAsset() {
            guard let image = UIImage(named: self.testImageName) else {
                XCTFail("failed to load image")
                return
            }
            let imageAsset = ImageAsset(image: image)
            XCTAssertNotNil(imageAsset)
    
            guard let asset = imageAsset.asset else {
                XCTFail("failed to get asset from image")
                return
            }
    
            print("constructed asset: \(asset)")
        }
    
    
    }
    

    Was originally going to do it as an extension on UIImage but then the deist made me move to a class.

提交回复
热议问题