MFMessageComposeViewController

  • 앱에서 메시지를 프로그래밍방식(Programmatically)으로 전송하기 위해서는 MFMessageComposeViewController를 사용해야 한다.
  • MFMessageComposeViewController는 메시지를 작성하고 전송하기 위한 표준 인터페이스를 제공한다.
  • 기타 다양한 지식은 애플의 MFMessageComposeViewController를 참고
  • 바로 사용법으로 넘어가보자

MFMessageComposeViewController 띄우기

import MessageUI
.
.
.
if MFMessageComposeViewController.canSendText() {
    // MFMessageComposeViewController를 띄우기 전, 꼭 canSendText를 확인해야 한다. 이 외에도 canSendAttachments(), canSendSubject() 등 목적에 맞게 확인해야 한다.
    let messageVC = MFMessageComposeViewController()
    self.present(messageVC, animated: true, completion:nil)
} else {
    // do something
}
.
.
.
  • 이렇게만 하면 MFMessageComposeViewController를 띄울 수 있다.

  • 그런데 여기까지만 하면 메시지를 보낼 수는 있는데 보내고 나서 혹은 취소 버튼을 눌러 dismiss를 할 수 없게 된다.

MFMessageComposeViewController 컨트롤

.
.
.
messageVC.messageComposeDelegate = self // Delegate 추가
.
.
.
// Delegate Method
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
    // do something
    controller.dismiss(animated: true, completion: nil)
}
  • MFMessageComposeViewController는 자동으로 dismiss되지 않는다.
  • 사용자가 메시지를 전송했거나, 취소 버튼을 누르면 messageComposeViewController(_:didFinishWith:)가 불린다.
  • 여기서 원하는 작업을 처리 후 dismiss 할 수 있다.
  • 이제 여기에 아래 사진을 참고해서 커스터마이징을 해보자

.
.
.
messageVC.body = "안녕하세요. 반갑습니다!!"
.
.
.


사용자의 기기에서 전화번호를 가져오기

  • 이 함수를 이용하면 사용자의 전화번호를 [String] 형태로 받아올 수 있다.
  • 참고로 messageVC.recipients의 타입도 [String] 이다.
import Contacts

func fetchPhoneNumbers(completionHandler: @escaping ([String]) -> Void) {
        var phoneNumbers = [String]()
        
        let store = CNContactStore()
        store.requestAccess(for: .contacts) { (isGranted, error) in
            if isGranted {
                let contactStore = CNContactStore()
                let keys = [CNContactPhoneNumbersKey]
                let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
                
                do {
                    try contactStore.enumerateContacts(with: request, usingBlock: { (contact, error) in
                        DispatchQueue.global().sync {
                            for phone in contact.phoneNumbers {
                                phoneNumbers.append(phone.value.stringValue)
                            }
                        }
                        completionHandler(phoneNumbers)
                    })
                } catch {
                    print(error)
                }
            }
        }
    }