Szybkie dzwonienie pod numer telefonu


89

Próbuję zadzwonić pod numer, który nie używa określonych numerów, ale numer, który jest wywoływany w zmiennej lub przynajmniej każę mu wywołać numer w telefonie. Ta liczba, która jest wywoływana w zmiennej, to liczba, którą pobrałem za pomocą parsera lub pobierając z witryny sql. Zrobiłem przycisk, próbując połączyć się z numerem telefonu przechowywanym w zmiennej z funkcją, ale bezskutecznie. Wszystko pomoże, dzięki!

    func callSellerPressed (sender: UIButton!){
 //(This is calls a specific number)UIApplication.sharedApplication().openURL(NSURL(string: "tel://######")!)

 // This is the code I'm using but its not working      
 UIApplication.sharedApplication().openURL(NSURL(scheme: NSString(), host: "tel://", path: busPhone)!)

        }

Odpowiedzi:


191

Spróbuj:

if let url = NSURL(string: "tel://\(busPhone)") where UIApplication.sharedApplication().canOpenURL(url) {
  UIApplication.sharedApplication().openURL(url)
}

zakładając, że numer telefonu jest w busPhone.

NSURL's init(string:)zwraca Opcjonalne, więc używając if letupewniamy się, że urljest to a NSURL(a nie NSURL?jak zwracane przez init).


Dla Swift 3:

if let url = URL(string: "tel://\(busPhone)"), UIApplication.shared.canOpenURL(url) {
    if #available(iOS 10, *) {
        UIApplication.shared.open(url)
    } else {
        UIApplication.shared.openURL(url)
    }
}

Musimy sprawdzić, czy korzystamy z iOS 10 lub nowszego, ponieważ:

„openURL” został wycofany w iOS 10.0


to daje mi błąd w postaci nierozwiązanego identyfikatora „url” - wskazuje na .openURL (url) Dzięki za pomoc!
Thomas Martinez

nvm brakowało mi tylko listu. ok, więc kiedy naciskam przycisk nic się nie dzieje. tutaj jest więcej informacji ---------- func parserDidEndDocument (parser: NSXMLParser!) {println (busPhone) drawUpdatedView ()}
Thomas Martinez

1
Testujesz to na telefonie? Podejrzewam, że otwarcie adresu tel: // URL będzie działać tylko na rzeczywistym iPhonie, a nie w symulatorze i nie na iPodzie lub iPadzie.
Thomas Müller,

Tak, testuję to na iPhonie 4s, klikam przycisk, ale nie podciąga numeru wywoływanego przez busPhone z serwera sql w moim telefonie. Kiedy używam tel: // z numerem telefonu, wybiera go.
Thomas Martinez,

2
OK, myślę, że wiem, w czym problem, ale nie wiem, jak go naprawić. Numer, który jest pobierany z adresu URL jest zapisany dokładnie tak, jak ten 123 456-7890, a nie jak ten 1234567890. Jak przetłumaczyć tel: //, aby odczytać adres URL w postaci, którą on rozpozna?
Thomas Martinez

66

Samodzielne rozwiązanie w iOS 10, Swift 3 :

private func callNumber(phoneNumber:String) {

  if let phoneCallURL = URL(string: "tel://\(phoneNumber)") {

    let application:UIApplication = UIApplication.shared
    if (application.canOpenURL(phoneCallURL)) {
        application.open(phoneCallURL, options: [:], completionHandler: nil)
    }
  }
}

Powinieneś być w stanie callNumber("7178881234")wykonać połączenie.


wyświetli błąd jak poniżej; „Ta aplikacja nie może wysyłać zapytań o schemat tel” dla swift 3 i czy działają one na symulatorze, czy nie?
Kiran jadhav

1
Ten kod nie będzie działał w symulatorze. Jeśli chcesz to sprawdzić, użyj urządzenia.
Ramakrishna

24

Swift 4,

private func callNumber(phoneNumber:String) {

    if let phoneCallURL = URL(string: "telprompt://\(phoneNumber)") {

        let application:UIApplication = UIApplication.shared
        if (application.canOpenURL(phoneCallURL)) {
            if #available(iOS 10.0, *) {
                application.open(phoneCallURL, options: [:], completionHandler: nil)
            } else {
                // Fallback on earlier versions
                 application.openURL(phoneCallURL as URL)

            }
        }
    }
}

13

Swift 3.0 i iOS 10 lub starszy

func phone(phoneNum: String) {
    if let url = URL(string: "tel://\(phoneNum)") {
        if #available(iOS 10, *) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
            UIApplication.shared.openURL(url as URL)
        }
    }
}

9

Ok, mam pomoc i rozgryzłem to. Dodałem też mały, fajny system ostrzegawczy na wypadek, gdyby numer telefonu był nieprawidłowy. Mój problem polegał na tym, że dzwoniłem dobrze, ale numer zawierał spacje i niepożądane znaki, takie jak („123 456-7890”). UIApplication działa lub akceptuje tylko wtedy, gdy Twój numer to („1234567890”). Więc zasadniczo usuwasz spację i nieprawidłowe znaki, tworząc nową zmienną, aby pobierać tylko liczby. Następnie dzwoni na te numery za pomocą aplikacji UIA.

func callSellerPressed (sender: UIButton!){
        var newPhone = ""

        for (var i = 0; i < countElements(busPhone); i++){

            var current:Int = i
            switch (busPhone[i]){
                case "0","1","2","3","4","5","6","7","8","9" : newPhone = newPhone + String(busPhone[i])
                default : println("Removed invalid character.")
            }
        }

        if  (busPhone.utf16Count > 1){

        UIApplication.sharedApplication().openURL(NSURL(string: "tel://" + newPhone)!)
        }
        else{
            let alert = UIAlertView()
            alert.title = "Sorry!"
            alert.message = "Phone number is not available for this business"
            alert.addButtonWithTitle("Ok")
                alert.show()
        }
        }

6
Myślę, że powinieneś także pozwolić na znak „+”.
florian

1
Również # jest jednym ze znaków używanych podczas składania żądań :)
iOSDev

9

Powyższe odpowiedzi są częściowo poprawne, ale z „tel: //” jest tylko jeden problem. Po zakończeniu połączenia powróci do ekranu głównego, a nie do naszej aplikacji. Więc lepiej użyć „telprompt: //”, powróci do aplikacji.

var url:NSURL = NSURL(string: "telprompt://1234567891")!
UIApplication.sharedApplication().openURL(url)

Najwyraźniej spowoduje to odrzucenie
Tom Knapen

8

Swift 3, iOS 10

func call(phoneNumber:String) {
        let cleanPhoneNumber = phoneNumber.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")
        let urlString:String = "tel://\(cleanPhoneNumber)"
        if let phoneCallURL = URL(string: urlString) {
            if (UIApplication.shared.canOpenURL(phoneCallURL)) {
                UIApplication.shared.open(phoneCallURL, options: [:], completionHandler: nil)
            }
        }
  }

options: [:], completionHandler: nilsą argumentami domyślnymi, możesz je pominąć.
Tim Vermeulen

7

Używam tej metody w mojej aplikacji i działa dobrze. Mam nadzieję, że to też może ci pomóc.

func makeCall(phone: String) {
    let formatedNumber = phone.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
    let phoneUrl = "tel://\(formatedNumber)"
    let url:NSURL = NSURL(string: phoneUrl)!
    UIApplication.sharedApplication().openURL(url)
}

6

Swift 5: iOS> = 10.0

Działa tylko na urządzeniu fizycznym.

private func callNumber(phoneNumber: String) {
    guard let url = URL(string: "telprompt://\(phoneNumber)"),
        UIApplication.shared.canOpenURL(url) else {
        return
    }
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}

Ktoś poniżej mówi, że jeśli użyjesz „telprompt” zamiast „tel”, Twoja aplikacja zostanie odrzucona.
Andy Weinstein

@AndyWeinstein eh, może jeśli to złapią, ale nie odrzucili żadnego z moich
grantespo

4

W Swift 3

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

4

Używam rozwiązania Swift 3 z walidacją liczb

var validPhoneNumber = ""
    phoneNumber.characters.forEach {(character) in
        switch character {
        case "0"..."9":
            validPhoneNumber.characters.append(character)
        default:
            break
        }
    }

    if UIApplication.shared.canOpenURL(URL(string: "tel://\(validNumber)")!){
        UIApplication.shared.openURL(URL(string: "tel://\(validNumber)")!)
    }

3

To jest aktualizacja odpowiedzi @ Toma przy użyciu Swift 2.0 Uwaga - to jest cała klasa CallComposer, której używam.

class CallComposer: NSObject {

var editedPhoneNumber = ""

func call(phoneNumber: String) -> Bool {

    if phoneNumber != "" {

        for i in number.characters {

            switch (i){
                case "0","1","2","3","4","5","6","7","8","9" : editedPhoneNumber = editedPhoneNumber + String(i)
                default : print("Removed invalid character.")
            }
        }

    let phone = "tel://" + editedPhoneNumber
        let url = NSURL(string: phone)
        if let url = url {
            UIApplication.sharedApplication().openURL(url)
        } else {
            print("There was an error")
        }
    } else {
        return false
    }

    return true
 }
}

2

Funkcja openURL () została wycofana w iOS 10. Oto nowa składnia:

if let url = URL(string: "tel://\(busPhone)") {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}

1
nie jest amortyzowany. zmiana w składni wynika z tego, że używasz szybkiego 3.
Hammadzafar

@Hammadzafar, metoda openURl (url) jest naprawdę przestarzała. Nowa wersja ma inny podpis, a także została zmieniona na open (url: options: completeHandler)
naśladuj

to dlatego, że swift 2.3 wkrótce zostanie zdekapitowany
Hammadzafar

2

Wiele innych odpowiedzi nie działa w przypadku Swift 5. Poniżej znajduje się aktualizacja kodu do Swift 5:

let formattedNumber = phoneNumberVariable.components(separatedBy: NSCharacterSet.decimalDigits.inverted).joined(separator: "")

if let url = NSURL(string: ("tel:" + (formattedNumber)!)) {
    if #available(iOS 10.0, *) {
        UIApplication.shared.open(url as URL, options: [:], completionHandler: nil)
    } else {
        UIApplication.shared.openURL(url as URL)
    }
}

PS:

  1. W przypadku większości odpowiedzi nie udało mi się wyświetlić monitu na urządzeniu. Powyższy kod z powodzeniem mógł wyświetlić monit.
  2. Nie ma // po tel: jak większość odpowiedzi. I działa dobrze.

1

Rozwiązanie Swift 3.0:

let formatedNumber = phone.components(separatedBy: NSCharacterSet.decimalDigits.inverted).joined(separator: "")
print("calling \(formatedNumber)")
let phoneUrl = "tel://\(formatedNumber)"
let url:URL = URL(string: phoneUrl)!
UIApplication.shared.openURL(url)

usuwa również znaki „+” i „#”
Amr Angry

1

Oto alternatywny sposób zredukowania numeru telefonu do prawidłowych komponentów za pomocą Scanner

let number = "+123 456-7890"

let scanner = Scanner(string: number)

let validCharacters = CharacterSet.decimalDigits
let startCharacters = validCharacters.union(CharacterSet(charactersIn: "+#"))

var digits: NSString?
var validNumber = ""
while !scanner.isAtEnd {
    if scanner.scanLocation == 0 {
        scanner.scanCharacters(from: startCharacters, into: &digits)
    } else {
        scanner.scanCharacters(from: validCharacters, into: &digits)
    }

    scanner.scanUpToCharacters(from: validCharacters, into: nil)
    if let digits = digits as? String {
        validNumber.append(digits)
    }
}

print(validNumber)

// +1234567890

1

Dla Swift 3.0

if let url = URL(string: "tel://\(number)"), UIApplication.shared.canOpenURL(url) {
    if #available(iOS 10, *) {
        UIApplication.shared.open(url)
    } else {
        UIApplication.shared.openURL(url)
    }
}
else {
    print("Your device doesn't support this feature.")
}

1

Dla Swift 4.2 i nowszych

if let phoneCallURL = URL(string: "tel://\(01234567)"), UIApplication.shared.canOpenURL(phoneCallURL)
{
    UIApplication.shared.open(phoneCallURL, options: [:], completionHandler: nil)
}

1
let formatedNumber = phone.components(separatedBy: NSCharacterSet.decimalDigits.inverted).joined(separator: "")
print("calling \(formatedNumber)")
let phoneUrl = "tel://\(formatedNumber)"
let url:URL = URL(string: phoneUrl)!
UIApplication.shared.openURL(url)

2
Chociaż ten fragment kodu może rozwiązać problem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod. Prosimy również starać się nie zatłaczać kodu komentarzami wyjaśniającymi, ponieważ zmniejsza to czytelność zarówno kodu, jak i wyjaśnień!
Rohan Khude


0

Aby uzyskać podejście zgodne ze standardem Swift 3.1 i wstecz, wykonaj następujące czynności:

@IBAction func phoneNumberButtonTouched(_ sender: Any) {
  if let number = place?.phoneNumber {
    makeCall(phoneNumber: number)
  }
}

func makeCall(phoneNumber: String) {
   let formattedNumber = phoneNumber.components(separatedBy: 
   NSCharacterSet.decimalDigits.inverted).joined(separator: "")

   let phoneUrl = "tel://\(formattedNumber)"
   let url:NSURL = NSURL(string: phoneUrl)!

   if #available(iOS 10, *) {
      UIApplication.shared.open(url as URL, options: [:], completionHandler: 
      nil)
   } else {
     UIApplication.shared.openURL(url as URL)
   }
}

0

Jeśli Twój numer telefonu zawiera spacje, najpierw je usuń! Następnie możesz użyć rozwiązania zaakceptowanej odpowiedzi .

let numbersOnly = busPhone.replacingOccurrences(of: " ", with: "")

if let url = URL(string: "tel://\(numbersOnly)"), UIApplication.shared.canOpenURL(url) {
    if #available(iOS 10, *) {
        UIApplication.shared.open(url)
    } else {
        UIApplication.shared.openURL(url)
    }
}

To pytanie zawiera teraz 17 odpowiedzi i ma ponad 3 lata. Dlaczego uznałeś za konieczne dodanie kolejnej odpowiedzi?
Fogmeister

1
Ponieważ nie rozumiałem, dlaczego nie działa, jeśli numer telefonu zawiera spację. Nie bądź taki negatywny, panie meister!
catanore

Zdecydowanie to rozumiem. Więc dodaj nowe pytanie wyraźnie dotyczące spacji w liczbach i dodaj własną odpowiedź. Nie ma nic złego w zadawaniu pytania i samodzielnym odpowiadaniu na nie. (Chociaż jestem prawie pewien, że pytanie to zostanie zamknięte jako duplikat).
Fogmeister

1
Nie, ważne jest, aby powiedzieć ludziom, dlaczego adres URL nie jest otwarty: ponieważ jest zerowy, ponieważ numer telefonu zawiera spacje. Z czym się zgadzam, to raczej komentarz niż odpowiedź. Ale jest tam zbyt wiele komentarzy.
catanore

Czy wzmianka o przestrzeniach ci pomogła?
catanore
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.