Expand Minimize Picture-in-picture Power Device Status Voice Recognition Skip Back Skip Forward Minus Plus Play Search
Internet Explorer alert
This browser is not recommended for use with smartdevicelink.com, and may not function properly. Upgrade to a different browser to guarantee support of all features.
close alert
To Top Created with Sketch. To Top
To Bottom Created with Sketch. To Bottom
iOS Guides
Calling a Phone Number

Calling a Phone Number

The SDLDialNumber RPC allows you make a phone call via the user's phone. In order to dial a phone number you must be sure that the device is connected via Bluetooth (even if your device is also connected using a USB cord) for this request to work. If the phone is not connected via Bluetooth, you will receive a result of REJECTED from the module.

Checking Your App's Permissions

SDLDialNumber is an RPC that is usually restricted by OEMs. As a result, a module may reject your request if your app does not have the correct permissions. Your SDL app may also be restricted to only being allowed to making a phone call when your app is open (i.e. the hmiLevel is non-NONE) or when it is the currently active app (i.e. the hmiLevel is FULL).

SDLPermissionElement *setDialNumberPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:SDLRPCFunctionNameDialNumber parameterPermissions:nil];

id observerId = [self.sdlManager.permissionManager subscribeToRPCPermissions:@[setDialNumberPermissionElement] groupType:SDLPermissionGroupTypeAny withHandler:^(NSDictionary<SDLPermissionRPCName, NSNumber *> * _Nonnull allChanges, SDLPermissionGroupStatus groupStatus) {
    if (groupStatus != SDLPermissionGroupStatusAllowed) {
        // Your app does not have permission to send the `SDLDialNumber` request for its current HMI level
        return;
    }

    // Your app has permission to send the `SDLDialNumber` request for its current HMI level
}];
let setDialNumberPermissionElement = SDLPermissionElement(rpcName: .dialNumber, parameterPermissions: nil)

let observerId = sdlManager.permissionManager.subscribe(toRPCPermissions: [setDialNumberPermissionElement], groupType: .any, withHandler: { (individualStatuses, groupStatus) in
    guard groupStatus == .allowed else {
        // Your app does not have permission to send the `SDLDialNumber` request for its current HMI level
        return
    }

    // Your app has permission to send the `SDLDialNumber` request for its current HMI level
})

Checking if the Module Supports Calling a Phone Number

Since making a phone call is a newer feature, there is a possibility that some legacy modules will reject your request because the module does not support the SDLDialNumber request. Once you have successfully connected to the module, you can check the module's capabilities via the SDLManager.systemCapabilityManager as shown in the example below. Please note that you only need to check once if the module supports calling a phone number, however you must wait to perform this check until you know that the SDL app has been opened (i.e. the hmiLevel is non-NONE).

Note

If you discover that the module does not support calling a phone number or that your app does not have the right permissions, you should disable any buttons, voice commands, menu items, etc. in your app that would send the SDLDialNumber request.

- (void)isDialNumberSupportedWithHandler:(void (^) (BOOL success, NSError * _Nullable error))handler {
    // Check if the module has phone capabilities
    if (![self.sdlManager.systemCapabilityManager isCapabilitySupported:SDLSystemCapabilityTypePhoneCall]) {
        return handler(false, nil);
    }

    // Legacy modules (pre-RPC Spec v4.5) do not support system capabilities, so for versions less than 4.5 we will assume `DialNumber` is supported if `isCapabilitySupported` returns true
    SDLMsgVersion *sdlMsgVersion = self.sdlManager.registerResponse.sdlMsgVersion;
    if (sdlMsgVersion == nil) {
        return handler(true, nil);
    }
    SDLVersion *rpcSpecVersion = [[SDLVersion alloc] initWithSDLMsgVersion:sdlMsgVersion];
    if (![rpcSpecVersion isGreaterThanOrEqualToVersion:[[SDLVersion alloc] initWithMajor:4 minor:5 patch:0]]) {
        return handler(true, nil);
    }

    // Check if the phone capability has already been retrieved from the module
    SDLPhoneCapability *phoneCapability = self.sdlManager.systemCapabilityManager.phoneCapability;
    if (phoneCapability != nil) {
        return handler(phoneCapability.dialNumberEnabled.boolValue, nil);
    }

    // Retrieve the phone capability from the module
    [self.sdlManager.systemCapabilityManager updateCapabilityType:SDLSystemCapabilityTypePhoneCall completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) {
        if (error != nil) {
            return handler(NO, error);
        }

        return handler(systemCapabilityManager.phoneCapability.dialNumberEnabled.boolValue, nil);
    }];
}
func isDialNumberSupported(handler: @escaping (_ success: Bool, _ error: Error?) -> Void) {
    // Check if the module has phone capabilities
    guard sdlManager.systemCapabilityManager.isCapabilitySupported(type: .phoneCall) else {
        return handler(false, nil)
    }

    // Legacy modules (pre-RPC Spec v4.5) do not support system capabilities, so for versions less than 4.5 we will assume `SDLDialNumber` is supported if `isCapabilitySupported` returns true
    guard let sdlMsgVersion = sdlManager.registerResponse?.sdlMsgVersion, SDLVersion(sdlMsgVersion: sdlMsgVersion).isGreaterThanOrEqual(to: SDLVersion(major: 4, minor: 5, patch: 0)) else {
        return handler(true, nil)
    }

    // Check if the phone capability has already been retrieved from the module
    if let phoneCapability = sdlManager.systemCapabilityManager.phoneCapability {
        return handler(phoneCapability.dialNumberEnabled?.boolValue ?? false, nil)
    }

    // Retrieve the phone capability from the module
    sdlManager.systemCapabilityManager.updateCapabilityType(.phoneCall) { (error, systemCapabilityManager) in
        if (error != nil) {
            return handler(false, error)
        }

        return handler(systemCapabilityManager.phoneCapability?.dialNumberEnabled?.boolValue ?? false, nil)
    }
}

Sending a DialNumber Request

Once you know that the module supports dialing a phone number and that your SDL app has permission to send the SDLDialNumber request, you can create and send the request.

Note

SDLDialNumber strips all characters except for 0-9, *, #, ,, ;, and +.

SDLDialNumber *dialNumber = [[SDLDialNumber alloc] initWithNumber: @"1238675309"];

[self.sdlManager sendRequest:dialNumber withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
    if (error != nil || ![response isKindOfClass:SDLDialNumberResponse.class]) {
        // Encountered error sending `SDLDialNumber`
        return;
    }

    SDLDialNumberResponse *dialNumber = (SDLDialNumberResponse *)response;
    SDLResult resultCode = dialNumber.resultCode;
    if (!resultCode.boolValue) {
        if ([resultCode isEqualToEnum:SDLResultRejected]) {
            // `SDLDialNumber` was rejected. Either the call was sent and cancelled or there is no device connected
        } else if ([resultCode isEqualToEnum:SDLResultDisallowed]) {
            // Your app is not allowed to use `SDLDialNumber`
        } else {
            // Some unknown error has occurred
        }
        return;
    }

    // `SDLDialNumber` successfully sent
}];
let dialNumber = SDLDialNumber(number: "1238675309")

sdlManager.send(request: dialNumber) { (request, response, error) in
    guard let response = response as? SDLDialNumberResponse, error == nil else {
        // Encountered error sending `SDLDialNumber`
        return
    }

    guard response.success.boolValue == true else {
        switch response.resultCode {
        case .rejected:
            // `SDLDialNumber` was rejected. Either the call was sent and cancelled or there is no device connected
        case .disallowed:
            // Your app is not allowed to use `SDLDialNumber`
        default:
            // Some unknown error has occurred
        }
        return
    }

    // `SDLDialNumber` successfully sent
}

Dial Number Responses

The SDLDialNumber request has three possible responses that you should expect:

  1. SUCCESS - The request was successfully sent, and a phone call was initiated by the user.
  2. REJECTED - This can mean either:

    • The user rejected the request to make the phone call.
    • The phone is not connected to the module via Bluetooth.
  3. DISALLOWED - Your app does not have permission to use the SDLDialNumber request.

View on GitHub.com
Previous Section Next Section