当我从jpeg文件中获取UIImage并将其另存为png文件时,它将无法与MSMessage一起使用。很难说是怎么回事,因为在连接到iPhone的Xcode中以调试模式运行iMessage扩展时,打印语句未打印。我只是注意到,当UIImage来自jpeg文件时,似乎有问题。
图像由包含的应用程序中的UIDocument子类从jpeg转换为png,并保存在iCloud中。在iMessage扩展中,使用相同的UIDocument子类在CollectionViewController的MSSticker中从iCloud检索图像。那部分工作正常。我认为问题出在MSMessage对象创建的时候。
这是我的代码:
UIDocument子类:
class ImageDocument: UIDocument {
var image: UIImage? = nil
override func load(fromContents contents: Any, ofType typeName: String?) throws {
guard let data = contents as? Data else {
throw DataFileError.fileReadFailed
}
image = UIImage(data: data)
}
override func contents(forType typeName: String) throws -> Any {
guard image != nil else {
throw DataFileError.badData
}
return image!.pngData() as Any
}
}
CollectionViewController中的图像选择器回调方法:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
print("!!! didFinishPickingMediaWithInfo")
picker.dismiss(animated: true, completion: nil)
var imageURL: URL?
var image: UIImage?
if #available(iOS 11.0, *) {
imageURL = info[UIImagePickerController.InfoKey.imageURL] as? URL
} else {
image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
}
let uuidString = UUID().uuidString
var saveToURL: URL = ubiquityDocumentsURL!
saveToURL.appendPathComponent(uuidString)
saveToURL.appendPathExtension("png")
print(saveToURL)
if let imageURL = imageURL {
if imageURL.pathExtension == saveToURL.pathExtension {
print("!!!!! path extensions equal !!!!!")
do {
try FileManager.default.copyItem(at: imageURL, to: saveToURL)
let document = ImageDocument(fileURL: saveToURL)
document.open() {
success in
if success {
let sticker = Sticker(rawValue: saveToURL.lastPathComponent, image: document.image!)
self.items.append(sticker)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
} // document.open()
} catch {
print(error.localizedDescription)
}
} else {
print("!!!!! imageURL.pathExtension=", imageURL.pathExtension)
let document = ImageDocument(fileURL: imageURL)
document.open() {
success in
if success {
document.save(to: saveToURL, for: UIDocument.SaveOperation.forCreating) {
(success: Bool) in
print("document.save success - ", success)
print("document.fileURL=", document.fileURL)
if success {
let sticker = Sticker(rawValue: saveToURL.lastPathComponent, image: document.image!)
self.items.append(sticker)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
}
}
} // if imageURL.pathExtension == saveToURL.pathExtension ELSE
} else if let image = image {
print("!!!!! image=", image as Any)
let document = ImageDocument(fileURL: saveToURL)
document.image = image
document.save(to: document.fileURL, for: UIDocument.SaveOperation.forCreating) {
(success: Bool) in
print("document.save success - ", success)
print("document.fileURL=", document.fileURL)
if success {
let sticker = Sticker(rawValue: saveToURL.lastPathComponent, image: image)
self.items.append(sticker)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
} else {
fatalError("Error in ViewController - both mediaURL and image are nil!")
}
}
CollectionViewController中的集合视图覆盖:
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let item = items[indexPath.row]
print("item=", item)
delegate?.selected(item)
}
从CollectionViewController触发的事件:
extension MessagesViewController: CollectionViewControllerDelegate {
func selected(_ sticker: Sticker) {
print("sticker=", sticker)
guard let conversation = activeConversation else { fatalError("Expected a conversation") }
// Create a new message with the same session as any currently selected message.
let message = composeMessage(with: sticker, caption: "messageCaption", session: conversation.selectedMessage?.session)
/// - Tag: InsertMessageInConversation
// Add the message to the conversation.
conversation.insert(message) { error in
if let error = error {
print(error)
}
}
}
}
辅助功能:
fileprivate func composeMessage(with sticker: Sticker, caption: String, session: MSSession? = nil) -> MSMessage {
let layout = MSMessageTemplateLayout()
layout.image = sticker.image
layout.caption = caption
print("layout.image=", layout.image as Any)
let message = MSMessage(session: session ?? MSSession())
message.layout = layout
return message
}
CollectionViewCell:
class CollectionViewCell: UICollectionViewCell {
static let reuseIdentifier = "CollectionViewCell"
var representedSticker: Sticker!
@IBOutlet weak var stickerView: MSStickerView!
}
Sticker类在CollectionViewController中用作数组“项目”,以显示在集合视图单元格中。
贴纸类:
protocol StickerProtocol {
var rawValue: String { get }
var image: UIImage { get set }
}
struct Sticker: StickerProtocol {
var rawValue: String
var image: UIImage
}