N.B:这不是一个重复的问题,我看过其他解决方案,但没有一个在Swift 3中工作,但是他们在Swift 2中工作。
我需要使用UIImagePickerController从照片库中获取图像,工作正常,然后我需要做的是以某种方式将其保存到CloudKit中的公共记录中,我对如何完成此操作非常开放。如果可能的话,请明确我需要更改/添加的内容以及在哪里。
我提供了我的整个视图控制器文件以确定。
导入UIKit 导入CloudKit
var email:String =“”
类ViewController:UIViewController,UITextFieldDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
//MARK: Properties
@IBOutlet weak var firstNameField: UITextField!
@IBOutlet weak var lastNameField: UITextField!
@IBOutlet weak var emailField: UITextField!
@IBOutlet weak var passwordField: UITextField!
@IBOutlet weak var confirmPasswordField: UITextField!
@IBOutlet weak var notMatching: UILabel!
@IBOutlet weak var emailLabel: UILabel!
@IBOutlet weak var errorLabel: UILabel!
@IBOutlet weak var photoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.firstNameField.autocorrectionType = .no
self.lastNameField.autocorrectionType = .no
self.emailField.autocorrectionType = .no
self.passwordField.autocorrectionType = .no
self.confirmPasswordField.autocorrectionType = .no
self.notMatching.isHidden = true
firstNameField.delegate = self
lastNameField.delegate = self
emailField.delegate = self
passwordField.delegate = self
confirmPasswordField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: UIImagePickerControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
// Dismiss the picker if the user canceled.
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// The info dictionary may contain multiple representations of the image. You want to use the original.
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image.
photoImageView.image = selectedImage
// Dismiss the picker.
dismiss(animated: true, completion: nil)
}
//MARK: Actions
@IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
//Hide keyboards
firstNameField.resignFirstResponder()
lastNameField.resignFirstResponder()
emailField.resignFirstResponder()
passwordField.resignFirstResponder()
confirmPasswordField.resignFirstResponder()
let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
@IBAction func signUpPressed(_ sender: UIButton) {
let container = CKContainer.default()
let pubDB = container.publicCloudDatabase
//let privDB = container.privateCloudDatabase
//Check if users exist
let query = CKQuery(recordType: "MyUsers", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
pubDB.perform(query, inZoneWith: nil, completionHandler: { (records, error) in
//error code 11 is no objects found
if error == nil || error?._code == 11 {
var emailExists = false
for record in records! {
if record.object(forKey: "email") as? String == self.emailField.text {
//other user with the same username exists - don't allow user to create account
emailExists = true
}
}
if emailExists == true {
self.emailLabel.text = "\(self.emailField.text!) is taken. Please choose another one."
} else {
if self.firstNameField.text != nil && self.lastNameField.text != nil && self.passwordField.text == self.confirmPasswordField.text {
//user can sign up
let record = CKRecord(recordType: "MyUsers")
record.setObject(self.emailField.text! as CKRecordValue?, forKey: "email")
record.setObject(self.passwordField.text! as CKRecordValue?, forKey: "password")
record.setObject(self.firstNameField.text! as CKRecordValue?, forKey: "firstName")
record.setObject(self.lastNameField.text! as CKRecordValue?, forKey: "lastName")
print("all good")
pubDB.save(record, completionHandler: { (record, error) in
if error == nil {
OperationQueue.main.addOperation {
UserDefaults.standard.set(self.emailField.text!, forKey: "Email")
email = self.emailField.text!
//self.performSegue(withIdentifier: "Games", sender: self)
}
} else {
print(error)
}
})
} else {
}
}
} else {
print(error)
}
})
}
// MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
}
谢谢!
答案 0 :(得分:6)
以下是使用CKAsset
将图片另存为CloudKit
的简单方法。请确保更改记录的名称,以及设置记录时资产的字段名称。
let documentsDirectoryPath:NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
var imageURL: URL!
let tempImageName = "Image2.jpg"
func saveImage(_ image: UIImage?) {
// Create a CKRecord
let newRecord:CKRecord = CKRecord(recordType: "<INSERT_RECORD_NAME")
if let image = image {
let imageData:Data = UIImageJPEGRepresentation(image, 1.0)!
let path:String = self.documentsDirectoryPath.appendingPathComponent(self.tempImageName)
try? UIImageJPEGRepresentation(image, 1.0)!.write(to: URL(fileURLWithPath: path), options: [.atomic])
self.imageURL = URL(fileURLWithPath: path)
try? imageData.write(to: self.imageURL, options: [.atomic])
let File:CKAsset? = CKAsset(fileURL: URL(fileURLWithPath: path))
newRecord.setObject(File, forKey: "<INSERT_RECORD_ASSET_FIELD_NAME")
}
if let database = self.publicDatabase {
database.save(newRecord, completionHandler: { (record:CKRecord?, error:Error?) in
// Check if there was an error
if error != nil {
NSLog((error?.localizedDescription)!)
}
else if let record = record {
// Do whatever you want with the record, but image record was saved, asset should be saved.
}
})
}
}
如果您无法JPEG
格式,并且需要另存为.png
,则可以将UIImageJPEGRepresentation
部分替换为:
let imageData:Data = UIImagePNGRepresentation(image)!
try? UIImagePNGRepresentation(image)!.write(to: URL(fileURLWithPath: path), options: [.atomic])
并使tempImageName
类似于let tempImageName = "Image2.png"
希望这有帮助
答案 1 :(得分:0)
Swift 5版本,但抽象为一个函数,可以在其中传递UI Image对象并返回要使用的URL。在将图像保存在CoreData中并想稍后再上传到CloudKit的地方很有用。
func getImageURL(for image: UIImage?) -> URL {
let documentsDirectoryPath:NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let tempImageName = "tempImage.jpg"
var imageURL: URL?
if let image = image {
let imageData:Data = image.jpegData(compressionQuality: 1.0)!
let path:String = documentsDirectoryPath.appendingPathComponent(tempImageName)
try? image.jpegData(compressionQuality: 1.0)!.write(to: URL(fileURLWithPath: path), options: [.atomic])
imageURL = URL(fileURLWithPath: path)
try? imageData.write(to: imageURL!, options: [.atomic])
}
return imageURL!
}
然后是我的用法:
let imageURL = getImageURL(for: UIImage(data: itemToPublish!.Photo!)!)
let imageAsset = CKAsset(fileURL: imageURL)
itemBeingUpdated["photo"] = imageAsset
CKContainer.default().publicCloudDatabase.save(challengeRecord) { ...