Когда я получаю UIImage из файла JPEG, а затем сохраняю его в виде файла PNG, он не будет работать с MSMessage. Трудно сказать, что происходит, потому что операторы print не печатаются, когда расширение iMessage запускается в режиме отладки в Xcode, подключенном к iPhone. Я только что заметил, что кажется, что есть проблема, когда UIImage пришел из файла JPEG.
Изображение преобразуется из JPEG в PNG и сохраняется в iCloud с помощью подкласса UIDocument в содержащем приложение. В расширении iMessage изображение извлекается из iCloud с использованием того же подкласса UIDocument и в MSSticker в CollectionViewController. Эта часть отлично работает. Я думаю, что когда объект 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!
}
Класс стикера используется в качестве «элементов» массива в CollectionViewController для отображения в ячейках представления коллекции.
Класс стикера:
protocol StickerProtocol {
var rawValue: String { get }
var image: UIImage { get set }
}
struct Sticker: StickerProtocol {
var rawValue: String
var image: UIImage
}