I have an iOS app in which there are 2 ways the user can get a picture:
Select it from photos library (UIImagePickerController
)
Click it from a custom made camera
Here is my code for clicking the image from a custom camera (this is within a custom class called Camera
, which is a subclass of UIView
)
func clickPicture(completion:@escaping (UIImage) -> Void) {
guard let videoConnection = stillImageOutput?.connection(withMediaType: AVMediaTypeVideo) else { return }
videoConnection.videoOrientation = .portrait
stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (sampleBuffer, error) -> Void in
guard let buffer = sampleBuffer else { return }
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer)
let dataProvider = CGDataProvider(data: imageData! as CFData)
let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)
let image = UIImage(cgImage: cgImageRef!, scale: 1, orientation: .right)
completion(image)
})
}
Here is how I click the image within the ViewController
:
@IBAction func clickImage(_ sender: AnyObject) {
cameraView.clickPicture { (image) in
//use "image" variable
}
}
Later, I attempt to upload this picture to the user's iCloud account using CloudKit
. However I receive an error saying the record is too large. I then came across this SO post, which says to use a CKAsset
. However, the only constructor for a CKAsset
requires a URL
.
Is there a generic way I can get a URL
from any UIImage
? Otherwise, how can get a URL
from the image I clicked using my custom camera (I have seen other posts about getting a url from a UIImagePickerController
)? Thanks!
CKAsset
represents some external file (image, video, binary data and etc). This is why it requires URL
as init parameter.
In your case I would recommend to use following steps to upload large image to CloudKit:
UIImage
to local storage (e.g. documents directory). CKAsset
with path to image in local storage. Here is some code:
// Save image.
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let filePath = "\(path)/MyImageName.jpg"
UIImageJPEGRepresentation(image, 1)!.writeToFile(filePath, atomically: true)
let asset = CKAsset(fileURL: NSURL(fileURLWithPath: filePath)!)
// Upload asset here.
// Delete image.
do {
try FileManager.default.removeItem(atPath: filePath)
} catch {
print(error)
}