如何使用 swift 使用云套件上传图片?
How to upload images with cloud kit using swift?
如何使用 swift 从 Cloud Kit 上传和加载图像?
我使用什么属性类型?
我使用什么代码?这是我目前使用的代码...
func SaveImageInCloud(ImageToSave: UIImage) {
let newRecord:CKRecord = CKRecord(recordType: "ImageRecord")
newRecord.setValue(ImageToSave, forKey: "Image")
if let database = self.privateDatabase {
database.saveRecord(newRecord, completionHandler: { (record:CKRecord!, error:NSError! ) in
if error != nil {
NSLog(error.localizedDescription)
}
else {
dispatch_async(dispatch_get_main_queue()) {
println("finished")
}
}
})
}
您需要在仪表板中为此值选择资产值类型。
newRecord.setValue(ImageToSave, forKey: "Image")
UIImage 不是 CKRecord
上允许的类型。您最好的选择是将此图像写入文件,然后创建一个 CKAsset
并将其记录在案。
您需要创建一个 CKAsset 并将其添加到您的记录中。你可以用这样的代码来做到这一点:
func SaveImageInCloud(ImageToSave: UIImage) {
let newRecord:CKRecord = CKRecord(recordType: "ImageRecord")
let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
if paths.count > 0 {
if let dirPath = paths[0] as? String {
let writePath = dirPath.stringByAppendingPathComponent("Image2.png")
UIImagePNGRepresentation(ImageToSave).writeToFile(writePath, atomically: true)
var File : CKAsset? = CKAsset(fileURL: NSURL(fileURLWithPath: writePath))
newRecord.setValue(File, forKey: "Image")
}
}
}
if let database = self.privateDatabase {
database.saveRecord(newRecord, completionHandler: { (record:CKRecord!, error:NSError! ) in
if error != nil {
NSLog(error.localizedDescription)
} else {
dispatch_async(dispatch_get_main_queue()) {
println("finished")
}
}
})
}
这里的内容与 Edwin 的回答类似,但更加简洁。我已经测试过了,效果很好。
此示例将 "myImage" UIImageView 保存到 "mySaveRecord" CKRecord 中,只需将这些名称替换为您各自的名称即可。
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
let imageFilePath = documentDirectory.stringByAppendingPathComponent("lastimage")
UIImagePNGRepresentation(myImage).writeToFile(imageFilePath, atomically: true)
let asset = CKAsset(fileURL: NSURL(fileURLWithPath: imageFilePath))
mySaveRecord.setObject(asset, forKey: "ProfilePicture")
CKContainer.defaultContainer().publicCloudDatabase.saveRecord(mySaveRecord, completionHandler: {
record, error in
if error != nil {
println("\(error)")
} else {
//record saved successfully!
}
})
此答案适用于 Swift 2.2 和 iOS 9,并将文件创建与上传分开,以便您可以针对两者进行适当的测试,因为它们是具有自身潜在问题的不同操作.
对于 uploadPhoto 函数,recordType 变量是您在 CloudKit 仪表板中使用的值。 photo["photo"] = asset
行中的 "photo" 键是您的记录类型的字段名称。
func uploadPhoto(image: UIImage, recordName: String) {
let privateDB = CKContainer.defaultContainer().privateCloudDatabase
let photoID = CKRecordID(recordName: recordName)
let photo = CKRecord(recordType: recordType, recordID: photoID)
let asset = CKAsset(fileURL: writeImage(image))
photo["photo"] = asset
privateDB.saveRecord(photo) { (record, error) in
guard error == nil else {
print(error?.localizedDescription)
return
}
print("Successful")
}
}
func writeImage(image: UIImage) -> NSURL {
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
let fileURL = documentsURL.URLByAppendingPathComponent(NSUUID().UUIDString + ".png")
if let imageData = UIImagePNGRepresentation(image) {
imageData.writeToURL(fileURL, atomically: false)
}
return fileURL
}
您可以通过以下方式调用它:
uploadPhoto(UIImage(named: "foo.png")!, recordName: "bar")
我在 Swift 5 中创建了这个小扩展,用于从 UIImage
转换为 CKAsset
:
extension UIImage {
func toCKAsset(name: String? = nil) -> CKAsset? {
guard let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {
return nil
}
guard let imageFilePath = NSURL(fileURLWithPath: documentDirectory)
.appendingPathComponent(name ?? "asset#\(UUID.init().uuidString)")
else {
return nil
}
do {
try self.pngData()?.write(to: imageFilePath)
return CKAsset(fileURL: imageFilePath)
} catch {
print("Error converting UIImage to CKAsset!")
}
return nil
}
}
然后您可以在问题中使用它:
if let asset = ImageToSave.toCKAsset() {
newRecord.setObject(asset, forKey: "Image")
CKContainer.defaultContainer().publicCloudDatabase.saveRecord(newRecord, completionHandler: {
record, error in
if error != nil {
println("\(error)")
} else {
// saved successfully!
}
})
}
如何使用 swift 从 Cloud Kit 上传和加载图像?
我使用什么属性类型?
我使用什么代码?这是我目前使用的代码...
func SaveImageInCloud(ImageToSave: UIImage) {
let newRecord:CKRecord = CKRecord(recordType: "ImageRecord")
newRecord.setValue(ImageToSave, forKey: "Image")
if let database = self.privateDatabase {
database.saveRecord(newRecord, completionHandler: { (record:CKRecord!, error:NSError! ) in
if error != nil {
NSLog(error.localizedDescription)
}
else {
dispatch_async(dispatch_get_main_queue()) {
println("finished")
}
}
})
}
您需要在仪表板中为此值选择资产值类型。
newRecord.setValue(ImageToSave, forKey: "Image")
UIImage 不是 CKRecord
上允许的类型。您最好的选择是将此图像写入文件,然后创建一个 CKAsset
并将其记录在案。
您需要创建一个 CKAsset 并将其添加到您的记录中。你可以用这样的代码来做到这一点:
func SaveImageInCloud(ImageToSave: UIImage) {
let newRecord:CKRecord = CKRecord(recordType: "ImageRecord")
let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
if paths.count > 0 {
if let dirPath = paths[0] as? String {
let writePath = dirPath.stringByAppendingPathComponent("Image2.png")
UIImagePNGRepresentation(ImageToSave).writeToFile(writePath, atomically: true)
var File : CKAsset? = CKAsset(fileURL: NSURL(fileURLWithPath: writePath))
newRecord.setValue(File, forKey: "Image")
}
}
}
if let database = self.privateDatabase {
database.saveRecord(newRecord, completionHandler: { (record:CKRecord!, error:NSError! ) in
if error != nil {
NSLog(error.localizedDescription)
} else {
dispatch_async(dispatch_get_main_queue()) {
println("finished")
}
}
})
}
这里的内容与 Edwin 的回答类似,但更加简洁。我已经测试过了,效果很好。
此示例将 "myImage" UIImageView 保存到 "mySaveRecord" CKRecord 中,只需将这些名称替换为您各自的名称即可。
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
let imageFilePath = documentDirectory.stringByAppendingPathComponent("lastimage")
UIImagePNGRepresentation(myImage).writeToFile(imageFilePath, atomically: true)
let asset = CKAsset(fileURL: NSURL(fileURLWithPath: imageFilePath))
mySaveRecord.setObject(asset, forKey: "ProfilePicture")
CKContainer.defaultContainer().publicCloudDatabase.saveRecord(mySaveRecord, completionHandler: {
record, error in
if error != nil {
println("\(error)")
} else {
//record saved successfully!
}
})
此答案适用于 Swift 2.2 和 iOS 9,并将文件创建与上传分开,以便您可以针对两者进行适当的测试,因为它们是具有自身潜在问题的不同操作.
对于 uploadPhoto 函数,recordType 变量是您在 CloudKit 仪表板中使用的值。 photo["photo"] = asset
行中的 "photo" 键是您的记录类型的字段名称。
func uploadPhoto(image: UIImage, recordName: String) {
let privateDB = CKContainer.defaultContainer().privateCloudDatabase
let photoID = CKRecordID(recordName: recordName)
let photo = CKRecord(recordType: recordType, recordID: photoID)
let asset = CKAsset(fileURL: writeImage(image))
photo["photo"] = asset
privateDB.saveRecord(photo) { (record, error) in
guard error == nil else {
print(error?.localizedDescription)
return
}
print("Successful")
}
}
func writeImage(image: UIImage) -> NSURL {
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
let fileURL = documentsURL.URLByAppendingPathComponent(NSUUID().UUIDString + ".png")
if let imageData = UIImagePNGRepresentation(image) {
imageData.writeToURL(fileURL, atomically: false)
}
return fileURL
}
您可以通过以下方式调用它:
uploadPhoto(UIImage(named: "foo.png")!, recordName: "bar")
我在 Swift 5 中创建了这个小扩展,用于从 UIImage
转换为 CKAsset
:
extension UIImage {
func toCKAsset(name: String? = nil) -> CKAsset? {
guard let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {
return nil
}
guard let imageFilePath = NSURL(fileURLWithPath: documentDirectory)
.appendingPathComponent(name ?? "asset#\(UUID.init().uuidString)")
else {
return nil
}
do {
try self.pngData()?.write(to: imageFilePath)
return CKAsset(fileURL: imageFilePath)
} catch {
print("Error converting UIImage to CKAsset!")
}
return nil
}
}
然后您可以在问题中使用它:
if let asset = ImageToSave.toCKAsset() {
newRecord.setObject(asset, forKey: "Image")
CKContainer.defaultContainer().publicCloudDatabase.saveRecord(newRecord, completionHandler: {
record, error in
if error != nil {
println("\(error)")
} else {
// saved successfully!
}
})
}