Почему UIImage из файла jpeg и сохраненный в файл png не отображаются как MSMessage в приложении iMessage? - PullRequest
0 голосов
/ 09 ноября 2018

Когда я получаю 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

}
...