49 Stimmen

Erkennen, ob das Gerät Telefonanrufe unterstützt oder nicht?

Ist der folgende Code zuverlässig, um festzustellen, ob ein Gerät Telefongespräche unterstützen kann oder nicht? Meine Sorge ist, wenn Apple die iphone Zeichenfolge in etwas anderes ändert, sagen wir, sie beschließen, "iphone 3g", "iphone 4" usw. zu haben.

[[UIDevice currentDevice].model isEqualToString:@"iPhone"]

100voto

Tommy Punkte 98519

Das iPhone unterstützt das URI-Schema tel://. Sie könnten also verwenden:

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];

canOpenURL: prüft explizit, ob es eine Anwendung gibt, die dieses URL-Schema öffnen kann, und nicht, ob die URL korrekt ist. Es spielt also keine Rolle, dass keine Telefonnummer angegeben ist. Die Methode gibt ein BOOL zurück, das Sie auf YES oder NO überprüfen sollten.

Das sollte buchstäblich die Frage beantworten, ob eine Anwendung vorhanden ist, die einen Telefonanruf tätigen kann. Es sollte also gegen künftige Änderungen der Gerätesegmentierung gewappnet sein.

65voto

AlBeebe Punkte 7953

Einfach zu prüfen, ob ein Gerät Telefonanrufe "unterstützt", ist vielleicht nicht die beste Lösung, je nachdem, was Sie erreichen wollen. Ob Sie es glauben oder nicht, manche Leute benutzen alte iPhones ohne Service, als wären sie ein iPod Touch. Manchmal haben die Leute keine SIM-Karten in ihren iPhones installiert. In meiner App wollte ich eine Telefonnummer wählen, wenn das Gerät des Benutzers dazu in der Lage ist, andernfalls wollte ich die Telefonnummer anzeigen und den Benutzer auffordern, ein Telefon zu nehmen und es zu wählen. Hier ist eine Lösung, die ich mir ausgedacht habe und die bis jetzt funktioniert hat. Fühlen Sie sich frei, sie zu kommentieren und zu verbessern.

// You must add the CoreTelephony.framework
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

-(bool)canDevicePlaceAPhoneCall {
    /*

     Returns YES if the device can place a phone call

     */

    // Check if the device can place a phone call
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]]) {
        // Device supports phone calls, lets confirm it can place one right now
        CTTelephonyNetworkInfo *netInfo = [[[CTTelephonyNetworkInfo alloc] init] autorelease];
        CTCarrier *carrier = [netInfo subscriberCellularProvider];
        NSString *mnc = [carrier mobileNetworkCode]; 
        if (([mnc length] == 0) || ([mnc isEqualToString:@"65535"])) {
            // Device cannot place a call at this time.  SIM might be removed.
            return NO;
        } else {
            // Device can place a phone call
            return YES;
        }
    } else {
        // Device does not support phone calls
        return  NO;
    }
}

Sie werden feststellen, dass ich prüfe, ob der mobileNetworkCode 65535 ist. Bei meinen Tests hat es den Anschein, dass der mobileNetworkCode auf 65535 gesetzt wird, wenn Sie die SIM-Karte entfernen. Ich bin mir nicht 100 % sicher, warum das so ist.

11voto

flo von der uni Punkte 738

Ich muss sicherstellen, dass eingehende Telefonanrufe die Aufnahmen meiner Kunden nicht unterbrechen können, also fordere ich sie auf, in den Flugzeugmodus zu wechseln, aber trotzdem das WLAN einzuschalten. Die obige Methode von AlBeebe hat bei mir unter iOS 8.1.3 nicht funktioniert, aber ich habe diese Lösung gefunden, die unter iOS 7 und später funktionieren sollte:

Sie müssen die Datei CoreTelephony.framework hinzufügen und importieren.

#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

Definieren Sie die Eigenschaft für Ihre Klasse, wenn Sie Änderungen verfolgen wollen

@property (strong, nonatomic) CTTelephonyNetworkInfo* networkInfo;  

Initiieren Sie die CTTelephonyNetworkInfo :

self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];

Und dann erhalten Sie einen Rückruf, wenn sich die Daten ändern:

- (void)radioAccessChanged {
    NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology);
}

Die Werte für currentRadioAccessTechnology sind definiert in CTTelephonyNetworkInfo.h definiert und man erhält null / nil zurück, wenn es keine Mobilfunkverbindung gibt.

Hier habe ich es gefunden: http://www.raywenderlich.com/48001/easily-overlooked-new-features-ios-7

10voto

Campbell_Souped Punkte 873

Auf der Grundlage der Antwort von @the-guardian habe ich mir folgendes ausgedacht (in Schnelldurchlauf):

import CoreTelephony

/**
 Indicates if the device can make a phone call.

 - seealso: [Source](http://stackoverflow.com/a/11595365/3643020)

 - returns: `true` if the device can make a phone call. `false` if not.
 */
final class func canMakePhoneCall() -> Bool {
    guard let url = URL(string: "tel://") else {
        return false
    }

    let mobileNetworkCode = CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode

    let isInvalidNetworkCode = mobileNetworkCode == nil
        || mobileNetworkCode?.count == 0
        || mobileNetworkCode == "65535"

    return UIApplication.shared.canOpenURL(url)
        && !isInvalidNetworkCode
}

Dieser Code wurde auf einem iPad Air 2 Wifi, einem iPad Air 2 Simulator und einem iPhone 6S Plus getestet und scheint ordnungsgemäß zu funktionieren. Wird auf einem iPad mit mobilen Daten bald bestimmen.

2voto

Julio Gorgé Punkte 10018

Ich glaube nicht, dass Ihre Methode zuverlässig ist, da sich die Gerätenamen in Zukunft ändern können. Wenn Sie verhindern möchten, dass die App auf Nicht-iPhone-Geräten ausgeführt wird, können Sie den Zusatz "telephony" in der UIRequiredDeviceCapabilities Wörterbuch in Ihrer Info.plist. Dadurch wird verhindert, dass andere Geräte als das iPhone Ihre App aus dem App Store herunterladen können.

Wenn Sie die 3G-Verbindung zu einem bestimmten Zeitpunkt überprüfen möchten, können Sie alternativ auch Apples Erreichbarkeit Dienstprogrammklasse zur Abfrage des aktuellen 3G/WIFI-Verbindungsstatus.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X