How to make phone call in iOS 10 using Swift? [duplicate]
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:
- Swift 5.2, Xcode 11.4 (11E146)
Solution
// MARK: DataDetectorclass DataDetector { private class func _find(all type: NSTextCheckingResult.CheckingType, in string: String, iterationClosure: (String) -> Bool) { guard let detector = try? NSDataDetector(types: type.rawValue) else { return } let range = NSRange(string.startIndex ..< string.endIndex, in: string) let matches = detector.matches(in: string, options: [], range: range) loop: for match in matches { for i in 0 ..< match.numberOfRanges { let nsrange = match.range(at: i) let startIndex = string.index(string.startIndex, offsetBy: nsrange.lowerBound) let endIndex = string.index(string.startIndex, offsetBy: nsrange.upperBound) let range = startIndex..<endIndex guard iterationClosure(String(string[range])) else { break loop } } } } class func find(all type: NSTextCheckingResult.CheckingType, in string: String) -> [String] { var results = [String]() _find(all: type, in: string) { results.append($0) return true } return results } class func first(type: NSTextCheckingResult.CheckingType, in string: String) -> String? { var result: String? _find(all: type, in: string) { result = $0 return false } return result }}// MARK: PhoneNumberstruct PhoneNumber { private(set) var number: String init?(extractFrom string: String) { guard let phoneNumber = PhoneNumber.first(in: string) else { return nil } self = phoneNumber } private init (string: String) { self.number = string } func makeACall() { guard 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) } } static func extractAll(from string: String) -> [PhoneNumber] { DataDetector.find(all: .phoneNumber, in: string) .compactMap { PhoneNumber(string: $0) } } static func first(in string: String) -> PhoneNumber? { guard let phoneNumberString = DataDetector.first(type: .phoneNumber, in: string) else { return nil } return PhoneNumber(string: phoneNumberString) }}extension PhoneNumber: CustomStringConvertible { var description: String { number } }// MARK: String extensionextension String { // MARK: Get remove all characters exept numbers func onlyDigits() -> String { let filtredUnicodeScalars = unicodeScalars.filter { CharacterSet.decimalDigits.contains($0) } return String(String.UnicodeScalarView(filtredUnicodeScalars)) } var detectedPhoneNumbers: [PhoneNumber] { PhoneNumber.extractAll(from: self) } var detectedFirstPhoneNumber: PhoneNumber? { PhoneNumber.first(in: self) }}
Usage
PhoneNumber(extractFrom: "+1-(800)-123-4567")?.makeACall()PhoneNumber.extractAll(from: "+1-(800)-123-4567 bla bla 1(617)111-22-33").last?.makeACall()PhoneNumber.first(in: "+1-(800)-123-4567 bla bla 1(617)111-22-33")?.makeACall()"+1-(800)-123-4567 bla bla 1(617)111-22-33".detectedPhoneNumbers[1].makeACall()"+1-(800)-123-4567 bla bla 1(617)111-22-33".detectedFirstPhoneNumber?.makeACall()
Full sample
do not forget to paste the solution code here
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("1(617)111-22-33!") isPhone("+44 1838 300284") isPhone("+44 1838 300284, 1 416 555 9292") isPhone("+44 1838 3d0384, 1 416 555 9292!")}private func isPhone(_ string: String) { let phoneNumbers = PhoneNumber.extractAll(from: string) let result = !phoneNumbers.isEmpty print("\(result ? "✅" : "❌") \(string) | detected phones: \(phoneNumbers)")}
Result
❌ blabla | detected phones: []✅ +1(222)333-44-55 | detected phones: [+1(222)333-44-55]✅ +42 555.123.4567 | detected phones: [555.123.4567]✅ +1-(800)-123-4567 | detected phones: [+1-(800)-123-4567]✅ +7 555 1234567 | detected phones: [+7 555 1234567]✅ +7(926)1234567 | detected phones: [+7(926)1234567]✅ (926) 1234567 | detected phones: [(926) 1234567]✅ +79261234567 | detected phones: [+79261234567]✅ 926 1234567 | detected phones: [926 1234567]✅ 9261234567 | detected phones: [9261234567]✅ 1234567 | detected phones: [1234567]✅ 123-4567 | detected phones: [123-4567]✅ 123-89-01 | detected phones: [123-89-01]✅ 495 1234567 | detected phones: [495 1234567]✅ 469 123 45 67 | detected phones: [469 123 45 67]✅ 8 (926) 1234567 | detected phones: [8 (926) 1234567]✅ 89261234567 | detected phones: [89261234567]✅ 926.123.4567 | detected phones: [926.123.4567]✅ 415-555-1234 | detected phones: [415-555-1234]✅ 650-555-2345 | detected phones: [650-555-2345]✅ (416)555-3456 | detected phones: [(416)555-3456]✅ 202 555 4567 | detected phones: [202 555 4567]✅ 4035555678 | detected phones: [4035555678]✅ 1 416 555 9292 | detected phones: [1 416 555 9292]✅ 1(617)111-22-33! | detected phones: [1(617)111-22-33]✅ +44 1838 300284 | detected phones: [+44 1838 300284]✅ +44 1838 300284, 1 416 555 9292 | detected phones: [+44 1838 300284, 1 416 555 9292]✅ +44 1838 3d0384, 1 416 555 9292! | detected phones: [1 416 555 9292]
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.