앱에서 메시지 앱 띄우기

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)
                }
            }
        }
    }