iOSの MessageKit による画像送信UIの作成
iOSの「MessageKit」による画像送信UIの作成を試したので、まとめました。
前回
1. コードの編集
前回のViewControllerのコードを編集して、画像送信UIを追加します。
(1) メディア (ChatMedia) の追加。
「MediaItem」を継承した画像情報を保持する構造体です。
// メディア
struct ChatMedia: MediaItem {
var url: URL?
var image: UIImage?
// プレースホルダー画像の取得
var placeholderImage: UIImage {
return UIImage()
}
// サイズの取得
var size: CGSize {
return CGSize(width: UIScreen.main.bounds.width/2, height: UIScreen.main.bounds.width/2)
}
// URLによるメディアの生成
static func new(url: URL?) -> ChatMedia {
ChatMedia(url: url, image: nil)
}
// 画像によるメディアの生成
static func new(image: UIImage?) -> ChatMedia {
ChatMedia(url: nil, image: image)
}
}
(2) メッセージ種別 (MessageKindType) の追加。
テキストメッセージと画像メッセージのどちらであるかを示す列挙型です。
// メッセージ種別
enum MessageKindType {
case text(message: String)
case image(mediaItem: ChatMedia)
}
(3) メッセージ (ChatMessage) をテキストと画像の両対応に変更。
// メッセージ
struct ChatMessage: MessageType {
var sender: SenderType // 送信者
var messageId: String // メッセージID
var sentDate: Date // 送信日時
var kindType: MessageKindType // 追加
// メッセージ種別
var kind: MessageKind {
switch kindType {
case .text(let message):
return .attributedText(NSAttributedString(
string: message,
attributes: [
.font: UIFont.systemFont(ofSize: 14.0),
.foregroundColor: sender.senderId == "0" ? UIColor.white : UIColor.label
]))
case .image(let mediaItem):
return .photo(mediaItem)
}
}
// テキストメッセージの生成
static func new(sender: SenderType, message: String) -> ChatMessage {
return ChatMessage(
sender: sender,
messageId: UUID().uuidString,
sentDate: Date(),
kindType: .text(message: message))
}
// 画像メッセージの生成
static func new(sender: SenderType, image: UIImage) -> ChatMessage {
return ChatMessage(
sender: sender,
messageId: UUID().uuidString,
sentDate: Date(),
kindType: .image(mediaItem: ChatMedia.new(image: image)))
}
}
(4) ViewControllerに写真ピッカー (picker) を追加。
「PhotosUI」のインポートとデリゲートも追加します。
import PhotosUI
// ViewController
final class ViewController: MessagesViewController {
:
// 写真ピッカー
private lazy var picker: PHPickerViewController = {
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.filter = .images
configuration.selectionLimit = 1
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
return picker
}()
:
}
// PHPickerViewControllerDelegate
extension ViewController: PHPickerViewControllerDelegate {
// 写真ピッカーで写真選択時に呼ばれる
func picker(_ picker: PHPickerViewController,
didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
results.forEach { result in
result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] item, error in
if let error = error {
debugPrint(error.localizedDescription)
} else if let image = item as? UIImage {
// 画像メッセージの追加
DispatchQueue.main.async {
let entity = ChatMessage.new(sender: ChatSender.me, image: image)
self?.messageList.append(entity)
}
}
}
}
}
}
(5) messageInputBarにクリップボタンの追加。
押下時に写真ピッカーを開きます。
// ビューロード時に呼ばれる
override func viewDidLoad() {
super.viewDidLoad()
:
// クリップボタンの追加
let clipBarButtonItem = InputBarButtonItem()
clipBarButtonItem.image = UIImage(systemName: "paperclip")
clipBarButtonItem.setSize(CGSize(width: 24.0, height: 36.0), animated: false)
clipBarButtonItem.onTouchUpInside { _ in
self.present(self.picker, animated: true, completion: nil)
}
messageInputBar.setStackViewItems([clipBarButtonItem, .flexibleSpace], forStack: .left, animated: false)
messageInputBar.setLeftStackViewWidthConstant(to: 36.0, animated: false)
}
2. 実行
実行すると、以下のようにクリップボタンから画像メッセージを送信できます。
この記事が気に入ったらサポートをしてみませんか?