How to make phone call in iOS 10 using Swift? [duplicate]

跟風遠走 提交于 2019-11-29 19:48:37

You can call like this:

 if let url = URL(string: "tel://\(number)") {
                UIApplication.shared.openURL(url)
            }

For Swift 3+, you can use like

guard let number = URL(string: "tel://" + number) else { return }
UIApplication.shared.open(number)

OR

UIApplication.shared.open(number, options: [:], completionHandler: nil)

Make sure you've scrubbed your phone number string to remove any instances of (, ), -, or space.

Task

Make a call with phone number validation

Details

Tested on:

  • Xcode 9.2, Swift 4
  • Xcode 10.2 (10E125), Swift 5

Solution

extension String {

    func extractAll(type: NSTextCheckingResult.CheckingType) -> [NSTextCheckingResult] {
        var result = [NSTextCheckingResult]()
        do {
            let detector = try NSDataDetector(types: type.rawValue)
            result = detector.matches(in: self, range: NSRange(startIndex..., in: self))
        } catch { print("ERROR: \(error)") }
        return result
    }

    func to(type: NSTextCheckingResult.CheckingType) -> String? {
        let phones = extractAll(type: type).compactMap { $0.phoneNumber }
        switch phones.count {
            case 0: return nil
            case 1: return phones.first
            default: print("ERROR: Detected several phone numbers"); return nil
        }
    }

    func onlyDigits() -> String {
        let filtredUnicodeScalars = unicodeScalars.filter{CharacterSet.decimalDigits.contains($0)}
        return String(String.UnicodeScalarView(filtredUnicodeScalars))
    }

    func makeAColl() {
        guard   let number = to(type: .phoneNumber),
                let url = URL(string: "tel://\(number.onlyDigits())"),
                UIApplication.shared.canOpenURL(url) else { return }
        if #available(iOS 10, *) {
            UIApplication.shared.open(url)
        } else {
            UIApplication.shared.openURL(url)
        }
    }
}

Usage

"+1-(800)-123-4567".makeAColl()

"phone:+1(617)111-22-33!".makeAColl() // Will extract "+1(617)111-22-33" and make a call

let text = "blabla, +1(222)333-44-55, dasdwedsczx acscas 123-89-01"
let phones = text.extractAll(type: .phoneNumber).compactMap { $0.phoneNumber }
print(phones)

Full sample

func test() {
    isPhone("blabla")
    isPhone("+1(222)333-44-55")
    isPhone("+42 555.123.4567")
    isPhone("+1-(800)-123-4567")
    isPhone("+7 555 1234567")
    isPhone("+7(926)1234567")
    isPhone("(926) 1234567")
    isPhone("+79261234567")
    isPhone("926 1234567")
    isPhone("9261234567")
    isPhone("1234567")
    isPhone("123-4567")
    isPhone("123-89-01")
    isPhone("495 1234567")
    isPhone("469 123 45 67")
    isPhone("8 (926) 1234567")
    isPhone("89261234567")
    isPhone("926.123.4567")
    isPhone("415-555-1234")
    isPhone("650-555-2345")
    isPhone("(416)555-3456")
    isPhone("202 555 4567")
    isPhone("4035555678")
    isPhone(" 1 416 555 9292")
    isPhone("+44 1838 300284")
    isPhone("+44 1838 300284, 1 416 555 9292")
}

private func isPhone(_ string: String) {
    let result = string.to(type: .phoneNumber) != nil
    print("\(result ? "✅" : "❌") \(string) | \(string.onlyDigits()) | \(result ? "[a phone number]" : "[not a phone number]")")
}

Result

❌ blabla |  | [not a phone number]
✅ +1(222)333-44-55 | 12223334455 | [a phone number]
✅ +42 555.123.4567 | 425551234567 | [a phone number]
✅ +1-(800)-123-4567 | 18001234567 | [a phone number]
✅ +7 555 1234567 | 75551234567 | [a phone number]
✅ +7(926)1234567 | 79261234567 | [a phone number]
✅ (926) 1234567 | 9261234567 | [a phone number]
✅ +79261234567 | 79261234567 | [a phone number]
✅ 926 1234567 | 9261234567 | [a phone number]
✅ 9261234567 | 9261234567 | [a phone number]
✅ 1234567 | 1234567 | [a phone number]
✅ 123-4567 | 1234567 | [a phone number]
✅ 123-89-01 | 1238901 | [a phone number]
✅ 495 1234567 | 4951234567 | [a phone number]
✅ 469 123 45 67 | 4691234567 | [a phone number]
✅ 8 (926) 1234567 | 89261234567 | [a phone number]
✅ 89261234567 | 89261234567 | [a phone number]
✅ 926.123.4567 | 9261234567 | [a phone number]
✅ 415-555-1234 | 4155551234 | [a phone number]
✅ 650-555-2345 | 6505552345 | [a phone number]
✅ (416)555-3456 | 4165553456 | [a phone number]
✅ 202 555 4567 | 2025554567 | [a phone number]
✅ 4035555678 | 4035555678 | [a phone number]
✅  1 416 555 9292 | 14165559292 | [a phone number]
✅ +44 1838 300284 | 441838300284 | [a phone number]
ERROR: Detected several phone numbers
❌ +44 1838 300284, 1 416 555 9292 | 44183830028414165559292 | [not a phone number]
["+1(222)333-44-55", "123-89-01"]

Updated for Swift 3:

used below simple lines of code, if you want to make a phone call:

// function defination:

func makeAPhoneCall()  {
    let url: NSURL = URL(string: "TEL://1234567890")! as NSURL
    UIApplication.shared.open(url as URL, options: [:], completionHandler: nil)
}

// function call: [Used anywhere in your code]

self.makeAPhoneCall()

Note: Please run the app on a real device because it won't work on the simulator.

In Swift 4.2

func dialNumber(number : String) {

 if let url = URL(string: "tel://\(number)"),
   UIApplication.shared.canOpenURL(url) {
      if #available(iOS 10, *) {
        UIApplication.shared.open(url, options: [:], completionHandler:nil)
       } else {
           UIApplication.shared.openURL(url)
       }
   } else {
            // add error message here 
   }
}

Call this like below

dialNumber(number: "+921111111222")

Hope this help.

if let phoneCallURL:URL = URL(string: "tel:\(strPhoneNumber)") {
        let application:UIApplication = UIApplication.shared
        if (application.canOpenURL(phoneCallURL)) {
            let alertController = UIAlertController(title: "MyApp", message: "Are you sure you want to call \n\(self.strPhoneNumber)?", preferredStyle: .alert)
            let yesPressed = UIAlertAction(title: "Yes", style: .default, handler: { (action) in
                application.openURL(phoneCallURL)
            })
            let noPressed = UIAlertAction(title: "No", style: .default, handler: { (action) in

            })
            alertController.addAction(yesPressed)
            alertController.addAction(noPressed)
            present(alertController, animated: true, completion: nil)
        }
    }

By mistake my answer was misplaced, please checkout this one: You can use this:

guard let url = URL(string: "tel://\(yourNumber)") else {
return //be safe
}

if #available(iOS 10.0, *) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.openURL(url)
}

We need to check whether we're on iOS 10 or later As 'openURL' was deprecated in iOS 10.0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!