Appeler un numéro de téléphone dans Swift

89

J'essaie d'appeler un numéro n'utilisant pas de numéros spécifiques, mais un numéro appelé dans une variable ou du moins lui dire de remonter le numéro de votre téléphone. Ce nombre qui est appelé dans une variable est un nombre que j'ai récupéré en utilisant un analyseur syntaxique ou en saisissant sur un site Web sql. J'ai fait un bouton en essayant d'appeler le numéro de téléphone stocké dans la variable avec une fonction mais en vain. Tout aidera merci!

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

        }
Thomas Martinez
la source

Réponses:

191

Essayez simplement:

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

en supposant que le numéro de téléphone est entré busPhone.

NSURL's init(string:)renvoie une option, donc en utilisant if letnous nous assurons que urlc'est a NSURL(et non a NSURL?comme renvoyé par le init).


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

Nous devons vérifier si nous sommes sur iOS 10 ou version ultérieure car:

'openURL' est obsolète dans iOS 10.0

Thomas Müller
la source
cela me donne une erreur d'identifiant non résolu 'url' - pointant vers le .openURL (url) Merci pour l'aide au fait!
Thomas Martinez
nvm il me manquait juste une lettre. ok alors quand j'appuie sur le bouton rien ne se passe. voici plus d'infos ---------- func parserDidEndDocument (parser: NSXMLParser!) {println (busPhone) drawUpdatedView ()}
Thomas Martinez
1
Testez-vous cela sur un téléphone? Je soupçonne que l'ouverture d'une URL tel: // ne fonctionnera que sur un iPhone réel, pas dans le simulateur et pas sur un iPod ou un iPad.
Thomas Müller
Oui, je le teste sur un iphone 4s, le bouton clique mais il ne tire pas le numéro appelé par busPhone à partir d'un serveur SQL sur mon téléphone. Lorsque j'utilise le tel: // avec un numéro de téléphone, il le compose.
Thomas Martinez
2
Ok, je pense que je sais quel est le problème mais je ne sais pas comment le résoudre. Le numéro qui est extrait de l'URL est écrit exactement comme ceci 123 456-7890 et pas comme ceci 1234567890. Comment traduire le tel: // pour lire l'URL sous la forme qu'il reconnaîtra?
Thomas Martinez
66

Une solution autonome dans 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)
    }
  }
}

Vous devriez pouvoir utiliser callNumber("7178881234")pour passer un appel.

Zorayr
la source
cela donnera une erreur comme ci-dessous; "Cette application n'est pas autorisée à interroger le schéma tel" pour swift 3 et est-ce que cela fonctionne sur simulateur ou non?
Kiran jadhav
1
Ce code ne fonctionnera pas dans le simulateur. Si vous souhaitez le vérifier, utilisez un appareil.
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)

            }
        }
    }
}
Teja
la source
13

Swift 3.0 et iOS 10 ou version antérieure

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)
        }
    }
}
Gandom
la source
9

D'accord, j'ai obtenu de l'aide et je l'ai compris. J'ai également mis en place un joli petit système d'alerte juste au cas où le numéro de téléphone ne serait pas valide. Mon problème était que je l'appelais correctement, mais le numéro contenait des espaces et des caractères indésirables tels que ("123 456-7890"). UIApplication ne fonctionne ou n'accepte que si votre numéro est ("1234567890"). Donc, vous supprimez essentiellement l'espace et les caractères invalides en créant une nouvelle variable pour extraire uniquement les nombres. Puis appelle ces numéros avec l'UIApplication.

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()
        }
        }
Thomas Martinez
la source
6
Vous devriez également autoriser le signe «+», je pense.
florian
1
Aussi # est l'un des caractères utilisés au moment de faire des requêtes :)
Le iOSDev
9

Les réponses ci-dessus sont partiellement correctes, mais avec "tel: //" il n'y a qu'un seul problème. Une fois l'appel terminé, il reviendra à l'écran d'accueil, pas à notre application. Il vaut donc mieux utiliser "telprompt: //", il reviendra à l'application.

var url:NSURL = NSURL(string: "telprompt://1234567891")!
UIApplication.sharedApplication().openURL(url)
Dipen Gajjar
la source
Apparemment, votre application sera rejetée
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)
            }
        }
  }
LuAndre
la source
options: [:], completionHandler: nilsont les arguments par défaut, vous pouvez les omettre.
Tim Vermeulen
7

J'utilise cette méthode dans mon application et cela fonctionne bien. J'espère que cela peut vous aider aussi.

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)
}
Ayath Khan
la source
6

Swift 5: iOS> = 10,0

Fonctionne uniquement sur un appareil physique.

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)
}
Grantespo
la source
Quelqu'un ci-dessous dit que si vous utilisez "telprompt" au lieu de "tel", votre application sera rejetée.
Andy Weinstein
@AndyWeinstein eh peut-être s'ils l'attrapent, mais ils n'ont rejeté aucun des miens
grantespo
4

Dans Swift 3,

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

J'utilise la solution swift 3 avec validation numérique

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)")!)
    }
Emmett
la source
3

Ceci est une mise à jour de la réponse de @ Tom utilisant Swift 2.0 Remarque - Il s'agit de toute la classe CallComposer que j'utilise.

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
 }
}
Michael McKenna
la source
2

openURL () est obsolète dans iOS 10. Voici la nouvelle syntaxe:

if let url = URL(string: "tel://\(busPhone)") {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
Torre Lasley
la source
1
ce n'est pas amorti. le changement de syntaxe est dû au fait que vous utilisez swift 3.
Hammadzafar
@Hammadzafar, la méthode openURl (url) est vraiment obsolète. La nouvelle version a une signature différente et a également été renommée pour ouvrir (url: options: completionHandler)
imiter
c'est parce que swift 2.3 va bientôt être déprécié
Hammadzafar
2

La plupart des autres réponses ne fonctionnent pas pour Swift 5. Vous trouverez ci-dessous la mise à jour du code vers 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. Avec la plupart des réponses, je n'ai pas pu obtenir l'invite sur l'appareil. Le code ci-dessus a réussi à afficher l'invite.
  2. Il n'y a pas de // après tel: comme la plupart des réponses l'ont fait. Et cela fonctionne très bien.
Mahendra Liya
la source
1

Solution 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)
Mazorati
la source
il supprime également les caractères «+» et «#»
Amr Angry
1

Voici une autre façon de réduire un numéro de téléphone à des composants valides en utilisant un 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
Ashley Mills
la source
1

Pour 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.")
}
Hardik Thakkar
la source
1

Pour Swift 4.2 et supérieur

if let phoneCallURL = URL(string: "tel://\(01234567)"), UIApplication.shared.canOpenURL(phoneCallURL)
{
    UIApplication.shared.open(phoneCallURL, options: [:], completionHandler: nil)
}
iHarshil
la source
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)
Jithin Pankaj k
la source
2
Bien que cet extrait de code puisse résoudre la question, inclure une explication contribue vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondez à la question aux lecteurs à l'avenir, et que ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, cela réduit la lisibilité du code et des explications!
Rohan Khude
0

Swift 3.0 et iOS 10+

UIApplication.shared.openURL(url) a été changé en UIApplication.shared.open(_ url: URL, options:[:], completionHandler completion: nil)

les options et le gestionnaire d'achèvement sont facultatifs, le rendu:

UIApplication.shared.open(url)

https://developer.apple.com/reference/uikit/uiapplication/1648685-open

RLoniello
la source
0

Pour une approche Swift 3.1 et rétrocompatible, procédez comme suit:

@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)
   }
}
Lauren Roth
la source
0

Si votre numéro de téléphone contient des espaces, supprimez-les d'abord! Ensuite, vous pouvez utiliser la solution de la réponse acceptée .

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)
    }
}
catanore
la source
Cette question contient désormais 17 réponses et date de plus de 3 ans. Pourquoi avez-vous jugé nécessaire d'ajouter encore une autre réponse?
Fogmeister
1
Parce que je n'ai pas compris pourquoi cela ne fonctionne pas si un numéro de téléphone contient de l'espace. Ne soyez pas si négatif, monsieur meister!
catanore
Comprenez bien cela. Ajoutez donc une nouvelle question explicitement sur les espaces dans les nombres et ajoutez-y votre propre réponse. Il n'y a rien de mal à poser une question et à y répondre vous-même. (Bien que je sois à peu près certain que cette question serait fermée en double).
Fogmeister
1
Non, il est important de dire aux gens ici pourquoi l'url n'est pas ouverte: parce que c'est nul, parce que le numéro de téléphone contient des espaces. Ce que je suis d'accord, c'est que cela devrait être plutôt un commentaire qu'une réponse. Mais il y a trop de commentaires là-bas.
catanore
La mention des espaces vous a-t-elle aidé?
catanore