How to tell if Cocoa Touch device can make calls? [duplicate]
Asked Answered
R

4

7

Possible Duplicate:
iOS - Detecting whether or not device support phone calls?

I'm writing an iPhone application that provides a button to call a phone number. I'm using code like the following to dial the number using a tel: URL in the usual way:

NSURL* contactTelURL = [NSURL
                        URLWithString:[NSString
                                       stringWithFormat:@"tel:%@",
                                       contactTel]];
[[UIApplication sharedApplication] openURL:contactTelURL];

It works fine on a real iPhone, but I just get an 'Unsupported URL' alert in the simulator. Presumably that would also happen on an iPod Touch, though I haven't tested that. It would be nice to remove the button when running on a device that won't make calls.

Is there a way to detect programatically whether a Cocoa Touch device can make phone calls?

Rase answered 24/5, 2009 at 15:10 Comment(0)
W
-1

You could query [[UIDevice currentDevice] model], and check if it is an iPhone.

Wallache answered 24/5, 2009 at 15:32 Comment(4)
This isn't the preferred solution. You should check which capabilities the device has, rather than testing for a specific model. See neilkimmett's answer.Krilov
This is the wrong answer, this question is a duplicate, and the right answer is provided here: #5095428Haphazard
This doesn't tell you if the device can make a call (i.e. it has a SIM, is on a network, etc)Shore
@MadsMobæk Do you basically mean that you should be doing an API check to see if an API for phone calls in available and then make the call if it is?Eyeshade
B
40

From Noah Witherspoon at Make a call from my iPhone application

the simulator doesn't support a lot of iOS's URL schemes, including those for the Phone, Maps, Youtube, and SMS apps. This is also the case for devices like the iPod touch and the iPad, which don't have phone capabilities; before using any URL scheme via -openURL:, you should check for support for that scheme using -canOpenURL:, which will return YES or NO depending on whether the current device supports the URL scheme you're using

So query [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]] to find out if the device can make calls.

Bethlehem answered 27/8, 2010 at 9:35 Comment(3)
this is the correct answer for me. It should always check -[UIApplication canOpenURL] before calling -[UIApplication openURL]Ingeringersoll
This is returning TRUE on my iPad 2 running iOS8.1. On the 8.1 simulator, however, it's returning FALSE. So this does not work on the actual device.Whidah
Maybe that has something to do with the continuity feature added in iOS 8?Narva
B
7

From iphonedevelopment.blogspot.com

#import <sys/utsname.h>

enum {
    MODEL_IPHONE_SIMULATOR,
    MODEL_IPOD_TOUCH,
    MODEL_IPHONE,
    MODEL_IPHONE_3G
};

@interface DeviceDetection : NSObject

+ (uint) detectDevice;
+ (NSString *) returnDeviceName:(BOOL)ignoreSimulator;

@end


@implementation DeviceDetection

+ (uint) detectDevice {
    NSString *model= [[UIDevice currentDevice] model];

    // Some iPod Touch return "iPod Touch", others just "iPod"

    NSString *iPodTouch = @"iPod Touch";
    NSString *iPodTouchLowerCase = @"iPod touch";
    NSString *iPodTouchShort = @"iPod";

    NSString *iPhoneSimulator = @"iPhone Simulator";

    uint detected;

    if ([model compare:iPhoneSimulator] == NSOrderedSame) {
        // iPhone simulator
        detected = MODEL_IPHONE_SIMULATOR;
    } else if ([model compare:iPodTouch] == NSOrderedSame) {
        // iPod Touch
        detected = MODEL_IPOD_TOUCH;
    } else if ([model compare:iPodTouchLowerCase] == NSOrderedSame) {
        // iPod Touch
        detected = MODEL_IPOD_TOUCH;
    } else if ([model compare:iPodTouchShort] == NSOrderedSame) {
        // iPod Touch
        detected = MODEL_IPOD_TOUCH;
    } else {
        // Could be an iPhone V1 or iPhone 3G (model should be "iPhone")
        struct utsname u;

        // u.machine could be "i386" for the simulator, "iPod1,1" on iPod Touch, "iPhone1,1" on iPhone V1 & "iPhone1,2" on iPhone3G

        uname(&u);

        if (!strcmp(u.machine, "iPhone1,1")) {
            detected = MODEL_IPHONE;
        } else {
            detected = MODEL_IPHONE_3G;
        }
    }
    return detected;
}


+ (NSString *) returnDeviceName:(BOOL)ignoreSimulator {
    NSString *returnValue = @"Unknown";

    switch ([DeviceDetection detectDevice]) {
        case MODEL_IPHONE_SIMULATOR:
            if (ignoreSimulator) {
                returnValue = @"iPhone 3G";
            } else {
                returnValue = @"iPhone Simulator";
            }
            break;
        case MODEL_IPOD_TOUCH:
            returnValue = @"iPod Touch";
            break;
        case MODEL_IPHONE:
            returnValue = @"iPhone";
            break;
        case MODEL_IPHONE_3G:
            returnValue = @"iPhone 3G";
            break;
        default:
            break;
    }        
    return returnValue;
}

@end
Bartender answered 24/5, 2009 at 21:10 Comment(0)
F
0

Here is a simple code snippet I use to check the device model is a phone and not a simulator to make sure it can make calls.

if ([[[UIDevice currentDevice] model] rangeOfString:@"Phone"].location != NSNotFound &&
    [[[UIDevice currentDevice] model] rangeOfString:@"Simulator"].location == NSNotFound ) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"tel:%@", number]  ] ];
}
Fer answered 12/4, 2011 at 4:56 Comment(0)
W
-1

You could query [[UIDevice currentDevice] model], and check if it is an iPhone.

Wallache answered 24/5, 2009 at 15:32 Comment(4)
This isn't the preferred solution. You should check which capabilities the device has, rather than testing for a specific model. See neilkimmett's answer.Krilov
This is the wrong answer, this question is a duplicate, and the right answer is provided here: #5095428Haphazard
This doesn't tell you if the device can make a call (i.e. it has a SIM, is on a network, etc)Shore
@MadsMobæk Do you basically mean that you should be doing an API check to see if an API for phone calls in available and then make the call if it is?Eyeshade

© 2022 - 2024 — McMap. All rights reserved.