summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2019-09-13 14:05:50 -0400
committerGitHub <noreply@github.com>2019-09-13 14:05:50 -0400
commit897d491f24c15f1e36e8574d7d9b8364f2a0e7d9 (patch)
tree8c6aee546daa828fb6abb70699d01fe3c2ac5593
parent8b783865896daa67a55b78d2ce9ff4127d21b0f8 (diff)
parent01274e356fbd40ebe7f9f690a0b30aa3cede7c93 (diff)
downloadsdl_ios-897d491f24c15f1e36e8574d7d9b8364f2a0e7d9.tar.gz
Merge pull request #1346 from smartdevicelink/feature/issue_1055_cancel_interaction_RPC
Implement SDL-0184 CancelInteraction RPC
-rw-r--r--Example Apps/Example ObjC/AlertManager.h9
-rw-r--r--Example Apps/Example ObjC/AlertManager.m26
-rw-r--r--Example Apps/Example Swift/AlertManager.swift16
-rw-r--r--Example Apps/Example Swift/VehicleDataManager.swift2
-rw-r--r--Example Apps/Shared/AppConstants.h8
-rw-r--r--Example Apps/Shared/AppConstants.m7
-rw-r--r--SmartDeviceLink-iOS.podspec2
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj24
-rw-r--r--SmartDeviceLink.podspec2
-rw-r--r--SmartDeviceLink/SDLAlert.h300
-rw-r--r--SmartDeviceLink/SDLAlert.m90
-rw-r--r--SmartDeviceLink/SDLCancelInteraction.h115
-rw-r--r--SmartDeviceLink/SDLCancelInteraction.m103
-rw-r--r--SmartDeviceLink/SDLCancelInteractionResponse.h20
-rw-r--r--SmartDeviceLink/SDLCancelInteractionResponse.m27
-rw-r--r--SmartDeviceLink/SDLChoiceSet.h11
-rw-r--r--SmartDeviceLink/SDLChoiceSet.m13
-rw-r--r--SmartDeviceLink/SDLChoiceSetManager.h13
-rw-r--r--SmartDeviceLink/SDLChoiceSetManager.m33
-rw-r--r--SmartDeviceLink/SDLFunctionID.m1
-rw-r--r--SmartDeviceLink/SDLLifecycleManager.m1
-rw-r--r--SmartDeviceLink/SDLNotificationConstants.h2
-rw-r--r--SmartDeviceLink/SDLNotificationConstants.m3
-rw-r--r--SmartDeviceLink/SDLNotificationDispatcher.m8
-rw-r--r--SmartDeviceLink/SDLPerformInteraction.h242
-rw-r--r--SmartDeviceLink/SDLPerformInteraction.m57
-rw-r--r--SmartDeviceLink/SDLPresentChoiceSetOperation.h28
-rw-r--r--SmartDeviceLink/SDLPresentChoiceSetOperation.m61
-rw-r--r--SmartDeviceLink/SDLPresentKeyboardOperation.h25
-rw-r--r--SmartDeviceLink/SDLPresentKeyboardOperation.m40
-rw-r--r--SmartDeviceLink/SDLProxyListener.h16
-rw-r--r--SmartDeviceLink/SDLRPCFunctionNames.h1
-rw-r--r--SmartDeviceLink/SDLRPCFunctionNames.m1
-rw-r--r--SmartDeviceLink/SDLRPCParameterNames.h2
-rw-r--r--SmartDeviceLink/SDLRPCParameterNames.m2
-rw-r--r--SmartDeviceLink/SDLScreenManager.h14
-rw-r--r--SmartDeviceLink/SDLScreenManager.m9
-rw-r--r--SmartDeviceLink/SDLScrollableMessage.h85
-rw-r--r--SmartDeviceLink/SDLScrollableMessage.m33
-rw-r--r--SmartDeviceLink/SDLSlider.h133
-rw-r--r--SmartDeviceLink/SDLSlider.m26
-rw-r--r--SmartDeviceLink/SmartDeviceLink.h2
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetManagerSpec.m59
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetSpec.m51
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m211
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m207
-rw-r--r--SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m4
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m554
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m142
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLPerformInteractionSpec.m351
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLScrollableMessageSpec.m130
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSliderSpec.m172
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLCancelInteractionResponseSpec.m41
-rw-r--r--SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m2
54 files changed, 2720 insertions, 817 deletions
diff --git a/Example Apps/Example ObjC/AlertManager.h b/Example Apps/Example ObjC/AlertManager.h
index bd803cec0..10508261a 100644
--- a/Example Apps/Example ObjC/AlertManager.h
+++ b/Example Apps/Example ObjC/AlertManager.h
@@ -14,7 +14,14 @@ NS_ASSUME_NONNULL_BEGIN
@interface AlertManager : NSObject
-+ (SDLAlert *)alertWithMessage:(NSString *)textField1 textField2:(nullable NSString *)textField2;
+/**
+ Creates an alert with up to two lines of text, an image, and a close button that will dismiss the alert when tapped.
+
+ @param textField1 The first line of the message to display in the alert
+ @param textField2 The second line of the message to display in the alert
+ @param iconName An image to show in the alert.
+ @return An SDLAlert object
+ */
+ (SDLAlert *)alertWithMessageAndCloseButton:(NSString *)textField1 textField2:(nullable NSString *)textField2 iconName:(nullable NSString *)iconName;
@end
diff --git a/Example Apps/Example ObjC/AlertManager.m b/Example Apps/Example ObjC/AlertManager.m
index d95bd2fc8..3efbba544 100644
--- a/Example Apps/Example ObjC/AlertManager.m
+++ b/Example Apps/Example ObjC/AlertManager.m
@@ -14,32 +14,12 @@ NS_ASSUME_NONNULL_BEGIN
@implementation AlertManager
-/**
- * Creates an alert with a single line of text
- *
- * @param textField1 The first line of a message to display in the alert
- * @param textField2 The second line of a message to display in the alert
- * @return An SDLAlert object
- */
-+ (SDLAlert *)alertWithMessage:(NSString *)textField1 textField2:(nullable NSString *)textField2 {
- return [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2];
++ (SDLSoftButton *)sdlex_okSoftButton {
+ return [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:AlertOKButtonText image:nil highlighted:YES buttonId:1 systemAction:nil handler:nil];
}
-/**
- Creates an alert with up to two lines of text and a close button that will dismiss the alert when tapped
-
- @param textField1 The first line of a message to display in the alert
- @param textField2 The second line of a message to display in the alert
- @param iconName The name of the uploaded icon artwork
- @return An SDLAlert object
- */
+ (SDLAlert *)alertWithMessageAndCloseButton:(NSString *)textField1 textField2:(nullable NSString *)textField2 iconName:(nullable NSString *)iconName {
- return [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2 alertText3:nil ttsChunks:nil playTone:NO progressIndicator:NO duration:5000 softButtons:@[[self sdlex_okSoftButton]] alertIcon:[[SDLImage alloc] initWithName:iconName isTemplate:YES]];
-}
-
-+ (SDLSoftButton *)sdlex_okSoftButton {
- SDLSoftButton *okSoftButton = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"OK" image:nil highlighted:YES buttonId:1 systemAction:nil handler:nil];
- return okSoftButton;
+ return [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2 alertText3:nil softButtons:@[[self.class sdlex_okSoftButton]] playTone:YES ttsChunks:nil duration:5000 progressIndicator:NO alertIcon:((iconName != nil) ? [[SDLImage alloc] initWithName:iconName isTemplate:YES] : nil) cancelID:0];
}
@end
diff --git a/Example Apps/Example Swift/AlertManager.swift b/Example Apps/Example Swift/AlertManager.swift
index 820f69f40..718210777 100644
--- a/Example Apps/Example Swift/AlertManager.swift
+++ b/Example Apps/Example Swift/AlertManager.swift
@@ -11,20 +11,10 @@ import SmartDeviceLink
class AlertManager {
private class var okSoftButton: SDLSoftButton {
- return SDLSoftButton(type: .text, text: "OK", image: nil, highlighted: true, buttonId: 1, systemAction: nil, handler: nil)
+ return SDLSoftButton(type: .text, text: AlertOKButtonText, image: nil, highlighted: true, buttonId: 1, systemAction: nil, handler: nil)
}
- /// Creates an alert with one or two lines of text.
- ///
- /// - Parameters:
- /// - textField1: The first line of a message to display in the alert
- /// - textField2: The second line of a message to display in the alert
- /// - Returns: An SDLAlert object
- class func alertWithMessage(_ textField1: String, textField2: String? = nil) -> SDLAlert {
- return SDLAlert(alertText1: textField1, alertText2: nil)
- }
-
- /// Creates an alert with up to two lines of text and a close button that will dismiss the alert when tapped
+ /// Creates an alert with up to two lines of text, an image, and a close button that will dismiss the alert when tapped.
///
/// - Parameters:
/// - textField1: The first line of a message to display in the alert
@@ -32,6 +22,6 @@ class AlertManager {
/// - iconName: The name of the uploaded icon artwork
/// - Returns: An SDLAlert object
class func alertWithMessageAndCloseButton(_ textField1: String, textField2: String? = nil, iconName: String? = nil) -> SDLAlert {
- return SDLAlert(alertText1: textField1, alertText2: textField2, alertText3: nil, ttsChunks: nil, playTone: false, progressIndicator: false, duration: 5000, softButtons: [AlertManager.okSoftButton], alertIcon: (iconName != nil) ? SDLImage(name: iconName!, isTemplate: true) : nil)
+ return SDLAlert(alertText1: textField1, alertText2: textField2, alertText3: nil, softButtons: [okSoftButton], playTone: true, ttsChunks: nil, duration: 5000, progressIndicator: false, alertIcon: (iconName != nil) ? SDLImage(name: iconName!, isTemplate: true) : nil, cancelID: 0)
}
}
diff --git a/Example Apps/Example Swift/VehicleDataManager.swift b/Example Apps/Example Swift/VehicleDataManager.swift
index 1d78edd42..34ac4352c 100644
--- a/Example Apps/Example Swift/VehicleDataManager.swift
+++ b/Example Apps/Example Swift/VehicleDataManager.swift
@@ -111,7 +111,7 @@ extension VehicleDataManager {
guard hasPermissionToAccessVehicleData(with: manager) else { return }
SDLLog.d("App has permission to access vehicle data. Requesting all vehicle data...")
- let getAllVehicleData = SDLGetVehicleData(accelerationPedalPosition: true, airbagStatus: true, beltStatus: true, bodyInformation: true, clusterModeStatus: true, deviceStatus: true, driverBraking: true, eCallInfo: true, electronicParkBrakeStatus: true, emergencyEvent: true, engineOilLife: true, engineTorque: true, externalTemperature: true, fuelLevel: true, fuelLevelState: true, fuelRange: true, gps: true, headLampStatus: true, instantFuelConsumption: true, myKey: true, odometer: true, prndl: true, rpm: true, speed: true, steeringWheelAngle: true, tirePressure: true, turnSignal: true, vin: true, wiperStatus: true)
+ let getAllVehicleData = SDLGetVehicleData(accelerationPedalPosition: true, airbagStatus: true, beltStatus: true, bodyInformation: true, cloudAppVehicleID: true, clusterModeStatus: true, deviceStatus: true, driverBraking: true, eCallInfo: true, electronicParkBrakeStatus: true, emergencyEvent: true, engineOilLife: true, engineTorque: true, externalTemperature: true, fuelLevel: true, fuelLevelState: true, fuelRange: true, gps: true, headLampStatus: true, instantFuelConsumption: true, myKey: true, odometer: true, prndl: true, rpm: true, speed: true, steeringWheelAngle: true, tirePressure: true, turnSignal: true, vin: true, wiperStatus: true)
manager.send(request: getAllVehicleData) { (request, response, error) in
guard didAccessVehicleDataSuccessfully(with: manager, response: response, error: error) else { return }
diff --git a/Example Apps/Shared/AppConstants.h b/Example Apps/Shared/AppConstants.h
index 9e7ec3d28..5fb4b25b0 100644
--- a/Example Apps/Shared/AppConstants.h
+++ b/Example Apps/Shared/AppConstants.h
@@ -47,11 +47,14 @@ extern NSString * const ImagesVisibleSoftButtonImageOffState;
extern NSString * const ImagesVisibleSoftButtonImageOnText;
extern NSString * const ImagesVisibleSoftButtonImageOffText;
-#pragma martk - SDL Text-To-Speech
+#pragma mark - Alert
+extern NSString * const AlertOKButtonText;
+
+#pragma mark - SDL Text-To-Speech
extern NSString * const TTSGoodJob;
extern NSString * const TTSYouMissed;
-#pragma martk - SDL Voice Commands
+#pragma mark - SDL Voice Commands
extern NSString * const VCStart;
extern NSString * const VCStop;
@@ -112,7 +115,6 @@ extern NSString * const ACTurnSignalMenuName;
extern NSString * const ACVINMenuName;
extern NSString * const ACWiperStatusMenuName;
-
#pragma mark - SDL Image Names
extern NSString * const AlertBWIconName;
extern NSString * const CarBWIconImageName;
diff --git a/Example Apps/Shared/AppConstants.m b/Example Apps/Shared/AppConstants.m
index 1760ecb42..ffe4762d1 100644
--- a/Example Apps/Shared/AppConstants.m
+++ b/Example Apps/Shared/AppConstants.m
@@ -44,11 +44,14 @@ NSString * const ImagesVisibleSoftButtonImageOffState = @"ImagesVisibleSoftButto
NSString * const ImagesVisibleSoftButtonImageOnText = @"➖Icons";
NSString * const ImagesVisibleSoftButtonImageOffText = @"➕Icons";
-#pragma mart - SDL Text-To-Speech
+#pragma mark - Alert
+NSString * const AlertOKButtonText = @"OK";
+
+#pragma mark - SDL Text-To-Speech
NSString * const TTSGoodJob = @"Good Job";
NSString * const TTSYouMissed = @"You Missed";
-#pragma martk - SDL Voice Commands
+#pragma mark - SDL Voice Commands
NSString * const VCStart = @"Start";
NSString * const VCStop = @"Stop";
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index bedd57cc4..66b0094b2 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -58,6 +58,8 @@ ss.public_header_files = [
'SmartDeviceLink/SDLButtonName.h',
'SmartDeviceLink/SDLButtonPress.h',
'SmartDeviceLink/SDLButtonPressMode.h',
+'SmartDeviceLink/SDLCancelInteraction.h',
+'SmartDeviceLink/SDLCancelInteractionResponse.h',
'SmartDeviceLink/SDLCarModeStatus.h',
'SmartDeviceLink/SDLCarWindowViewController.h',
'SmartDeviceLink/SDLChangeRegistration.h',
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 3c9c81413..7d20f6f57 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -1289,6 +1289,7 @@
8818ADD82100FC18007D6F19 /* SDLTurnSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8818ADD62100FC18007D6F19 /* SDLTurnSignal.h */; settings = {ATTRIBUTES = (Public, ); }; };
8818ADD92100FC18007D6F19 /* SDLTurnSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = 8818ADD72100FC18007D6F19 /* SDLTurnSignal.m */; };
8818ADDD2100FE0C007D6F19 /* SDLTurnSignalSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8818ADDC2100FE0C007D6F19 /* SDLTurnSignalSpec.m */; };
+ 881F388D22D904BE00DF6DCE /* SDLCancelInteractionResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 881F388C22D904BE00DF6DCE /* SDLCancelInteractionResponseSpec.m */; };
8829568B207CF68800EF056C /* SmartDeviceLink.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D61FA1C1A84237100846EE7 /* SmartDeviceLink.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
88295693207CF68800EF056C /* SmartDeviceLink.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5D61FA1C1A84237100846EE7 /* SmartDeviceLink.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
882C42CE2108CDB100A44B58 /* (null) in Sources */ = {isa = PBXBuildFile; };
@@ -1445,6 +1446,11 @@
88EED83B1F33BECB00E6C42E /* SDLHapticRectSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88EED83A1F33BECB00E6C42E /* SDLHapticRectSpec.m */; };
88EED83E1F33C5A400E6C42E /* SDLSendHapticData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88EED83C1F33C5A400E6C42E /* SDLSendHapticData.h */; settings = {ATTRIBUTES = (Public, ); }; };
88EED83F1F33C5A400E6C42E /* SDLSendHapticData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88EED83D1F33C5A400E6C42E /* SDLSendHapticData.m */; };
+ 88EF8EB722D8E02E00CB06C2 /* SDLCancelInteraction.h in Headers */ = {isa = PBXBuildFile; fileRef = 88EF8EB522D8E02E00CB06C2 /* SDLCancelInteraction.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 88EF8EB822D8E02E00CB06C2 /* SDLCancelInteraction.m in Sources */ = {isa = PBXBuildFile; fileRef = 88EF8EB622D8E02E00CB06C2 /* SDLCancelInteraction.m */; };
+ 88EF8EBA22D8F48300CB06C2 /* SDLCancelInteractionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88EF8EB922D8F48300CB06C2 /* SDLCancelInteractionSpec.m */; };
+ 88EF8EBD22D8FE5800CB06C2 /* SDLCancelInteractionResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 88EF8EBB22D8FE5800CB06C2 /* SDLCancelInteractionResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 88EF8EBE22D8FE5800CB06C2 /* SDLCancelInteractionResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 88EF8EBC22D8FE5800CB06C2 /* SDLCancelInteractionResponse.m */; };
88F37A4D226F84BE00DF119B /* SDLIAPDataSessionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F37A4C226F84BE00DF119B /* SDLIAPDataSessionSpec.m */; };
88F50D5F220B720E00F34648 /* SDLPerformAppServiceInteractionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F50D5E220B720E00F34648 /* SDLPerformAppServiceInteractionSpec.m */; };
88F65133220C6DC300CAF321 /* SDLWeatherAlertSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */; };
@@ -3010,6 +3016,7 @@
8818ADD62100FC18007D6F19 /* SDLTurnSignal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLTurnSignal.h; sourceTree = "<group>"; };
8818ADD72100FC18007D6F19 /* SDLTurnSignal.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLTurnSignal.m; sourceTree = "<group>"; };
8818ADDC2100FE0C007D6F19 /* SDLTurnSignalSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLTurnSignalSpec.m; sourceTree = "<group>"; };
+ 881F388C22D904BE00DF6DCE /* SDLCancelInteractionResponseSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLCancelInteractionResponseSpec.m; sourceTree = "<group>"; };
88295697207CF68800EF056C /* SDL Example Swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SDL Example Swift.app"; sourceTree = BUILT_PRODUCTS_DIR; };
882FAC4C2209D7EF0062385D /* SDLAppServiceDataSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLAppServiceDataSpec.m; sourceTree = "<group>"; };
8831FA382201E3D100B8FFB7 /* SDLAppServiceManifestSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLAppServiceManifestSpec.m; sourceTree = "<group>"; };
@@ -3164,6 +3171,11 @@
88EED83A1F33BECB00E6C42E /* SDLHapticRectSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLHapticRectSpec.m; sourceTree = "<group>"; };
88EED83C1F33C5A400E6C42E /* SDLSendHapticData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLSendHapticData.h; sourceTree = "<group>"; };
88EED83D1F33C5A400E6C42E /* SDLSendHapticData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSendHapticData.m; sourceTree = "<group>"; };
+ 88EF8EB522D8E02E00CB06C2 /* SDLCancelInteraction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLCancelInteraction.h; sourceTree = "<group>"; };
+ 88EF8EB622D8E02E00CB06C2 /* SDLCancelInteraction.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLCancelInteraction.m; sourceTree = "<group>"; };
+ 88EF8EB922D8F48300CB06C2 /* SDLCancelInteractionSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLCancelInteractionSpec.m; sourceTree = "<group>"; };
+ 88EF8EBB22D8FE5800CB06C2 /* SDLCancelInteractionResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLCancelInteractionResponse.h; sourceTree = "<group>"; };
+ 88EF8EBC22D8FE5800CB06C2 /* SDLCancelInteractionResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLCancelInteractionResponse.m; sourceTree = "<group>"; };
88F37A4C226F84BE00DF119B /* SDLIAPDataSessionSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLIAPDataSessionSpec.m; sourceTree = "<group>"; };
88F50D5E220B720E00F34648 /* SDLPerformAppServiceInteractionSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLPerformAppServiceInteractionSpec.m; sourceTree = "<group>"; };
88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherAlertSpec.m; sourceTree = "<group>"; };
@@ -3596,6 +3608,7 @@
8877F5EA1F34A3BE00DC128A /* SDLSendHapticDataSpec.m */,
9FA0D00822DF0B47009CF344 /* SDLCreateWindowSpec.m */,
9FA0D00E22DF0B90009CF344 /* SDLDeleteWindowSpec.m */,
+ 88EF8EB922D8F48300CB06C2 /* SDLCancelInteractionSpec.m */,
8B05F88822DD011300666CD8 /* SDLUnpublishAppServiceSpec.m */,
000DD56F22EF038C005AB7A7 /* SDLGetInteriorVehicleDataConsentSpec.m */,
000DD57322EF0957005AB7A7 /* SDLReleaseInteriorVehicleDataModuleSpec.m */,
@@ -3666,6 +3679,7 @@
DA9F7EAB1DCC062400ACAE48 /* SDLUnsubscribeWaypointsResponseSpec.m */,
162E828D1A9BDE8A00906325 /* SDLUpdateTurnListResponseSpec.m */,
8877F5F01F34AA2D00DC128A /* SDLSendHapticDataResponseSpec.m */,
+ 881F388C22D904BE00DF6DCE /* SDLCancelInteractionResponseSpec.m */,
8BA12B1722DCF59700371E82 /* SDLUnpublishAppServiceResponseSpec.m */,
000DD57122EF063F005AB7A7 /* SDLGetInteriorVehicleDataConsentResponseSpec.m */,
000DD57522EF0971005AB7A7 /* SDLReleaseInteriorVehicleDataModuleResponseSpec.m */,
@@ -4295,6 +4309,8 @@
5D61FA4D1A84238A00846EE7 /* SDLAlertManeuver.m */,
1E5AD07E1F20B73E0029B8AF /* SDLButtonPress.h */,
1E5AD07F1F20B73E0029B8AF /* SDLButtonPress.m */,
+ 88EF8EB522D8E02E00CB06C2 /* SDLCancelInteraction.h */,
+ 88EF8EB622D8E02E00CB06C2 /* SDLCancelInteraction.m */,
5D61FA6E1A84238A00846EE7 /* SDLChangeRegistration.h */,
5D61FA6F1A84238A00846EE7 /* SDLChangeRegistration.m */,
888DBAE922D52431002A0AE2 /* SDLCloseApplication.h */,
@@ -4426,6 +4442,8 @@
5D61FA511A84238A00846EE7 /* SDLAlertResponse.m */,
1E5AD0821F20B9290029B8AF /* SDLButtonPressResponse.h */,
1E5AD0831F20B9290029B8AF /* SDLButtonPressResponse.m */,
+ 88EF8EBB22D8FE5800CB06C2 /* SDLCancelInteractionResponse.h */,
+ 88EF8EBC22D8FE5800CB06C2 /* SDLCancelInteractionResponse.m */,
5D61FA701A84238A00846EE7 /* SDLChangeRegistrationResponse.h */,
5D61FA711A84238A00846EE7 /* SDLChangeRegistrationResponse.m */,
888DBAED22D528DE002A0AE2 /* SDLCloseApplicationResponse.h */,
@@ -6787,6 +6805,7 @@
5D535DC51B72473800CF7760 /* SDLGlobals.h in Headers */,
5D79A03B1CE36F030035797B /* SDLUploadFileOperation.h in Headers */,
8880D24722205B1B00964F6A /* SDLNavigationInstruction.h in Headers */,
+ 88EF8EB722D8E02E00CB06C2 /* SDLCancelInteraction.h in Headers */,
DA9F7E6F1DCBFFDB00ACAE48 /* SDLGetWayPoints.h in Headers */,
5D61FD231A84238C00846EE7 /* SDLParameterPermissions.h in Headers */,
5D61FCB91A84238C00846EE7 /* SDLGlobalProperty.h in Headers */,
@@ -6916,6 +6935,7 @@
5D61FCFC1A84238C00846EE7 /* SDLRPCParameterNames.h in Headers */,
DA9F7E8F1DCC04C000ACAE48 /* SDLUnsubscribeWayPointsResponse.h in Headers */,
5D61FCFD1A84238C00846EE7 /* SDLObjectWithPriority.h in Headers */,
+ 88EF8EBD22D8FE5800CB06C2 /* SDLCancelInteractionResponse.h in Headers */,
888DBAEF22D528DE002A0AE2 /* SDLCloseApplicationResponse.h in Headers */,
DAC5726C1D11B4840004288B /* SDLTouchManagerDelegate.h in Headers */,
5D61FD3F1A84238C00846EE7 /* SDLPrioritizedObjectCollection.h in Headers */,
@@ -7431,6 +7451,7 @@
5D61FD511A84238C00846EE7 /* SDLProxy.m in Sources */,
5D61FD461A84238C00846EE7 /* SDLProtocolHeader.m in Sources */,
5DD8406320FCD6C10082CE04 /* SDLElectronicParkBrakeStatus.m in Sources */,
+ 88EF8EB822D8E02E00CB06C2 /* SDLCancelInteraction.m in Sources */,
8BBEA6071F324165003EEA26 /* SDLMetadataType.m in Sources */,
5DA150C82271FDC20032928D /* SDLSoftButtonTransitionOperation.m in Sources */,
9FE2471222D77AA400F8D2FC /* SDLCreateWindowResponse.m in Sources */,
@@ -7499,6 +7520,7 @@
DA9F7E901DCC04C000ACAE48 /* SDLUnsubscribeWayPointsResponse.m in Sources */,
88F65137220C74FD00CAF321 /* SDLWeatherData.m in Sources */,
5DA150CE2271FE180032928D /* SDLSoftButtonReplaceOperation.m in Sources */,
+ 88EF8EBE22D8FE5800CB06C2 /* SDLCancelInteractionResponse.m in Sources */,
5DE372A21ACB2ED300849FAA /* SDLHMICapabilities.m in Sources */,
5D61FDD41A84238C00846EE7 /* SDLTouchEvent.m in Sources */,
5D61FD881A84238C00846EE7 /* SDLSetGlobalProperties.m in Sources */,
@@ -7720,6 +7742,7 @@
88F65133220C6DC300CAF321 /* SDLWeatherAlertSpec.m in Sources */,
5DC09EDA1F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m in Sources */,
1EB59CCE202DC97900343A61 /* SDLMassageCushionSpec.m in Sources */,
+ 88EF8EBA22D8F48300CB06C2 /* SDLCancelInteractionSpec.m in Sources */,
162E83041A9BDE8B00906325 /* SDLUpdateModeSpec.m in Sources */,
8855F9E0220C93B700A5C897 /* SDLWeatherDataSpec.m in Sources */,
88DF998D22035CC600477AC1 /* EAAccessory+OCMock.m in Sources */,
@@ -7979,6 +8002,7 @@
5D43466F1E6F55BD00B639C6 /* SDLLogManagerSpec.m in Sources */,
162E83451A9BDE8B00906325 /* SDLUnregisterAppInterfaceSpec.m in Sources */,
162E82EF1A9BDE8B00906325 /* SDLPermissionStatusSpec.m in Sources */,
+ 881F388D22D904BE00DF6DCE /* SDLCancelInteractionResponseSpec.m in Sources */,
8BA12B1822DCF59700371E82 /* SDLUnpublishAppServiceResponseSpec.m in Sources */,
DA9F7EA61DCC05F500ACAE48 /* SDLUnsubscribeWaypointsSpec.m in Sources */,
1E89B0E2203196B800A47992 /* SDLSeatControlCapabilitiesSpec.m in Sources */,
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index bc327557e..ff8e32243 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -59,6 +59,8 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLButtonName.h',
'SmartDeviceLink/SDLButtonPress.h',
'SmartDeviceLink/SDLButtonPressMode.h',
+'SmartDeviceLink/SDLCancelInteraction.h',
+'SmartDeviceLink/SDLCancelInteractionResponse.h',
'SmartDeviceLink/SDLCarModeStatus.h',
'SmartDeviceLink/SDLCarWindowViewController.h',
'SmartDeviceLink/SDLChangeRegistration.h',
diff --git a/SmartDeviceLink/SDLAlert.h b/SmartDeviceLink/SDLAlert.h
index a0a8329c5..6a9a25e57 100644
--- a/SmartDeviceLink/SDLAlert.h
+++ b/SmartDeviceLink/SDLAlert.h
@@ -8,158 +8,254 @@
@class SDLSoftButton;
@class SDLTTSChunk;
+NS_ASSUME_NONNULL_BEGIN
+
/**
- * Shows an alert which typically consists of text-to-speech message and text on the display. At least either alertText1, alertText2 or TTSChunks need to be provided.
- *
- * <ul>
- * <li>The displayed portion of the SDLAlert, if any, will persist until the
- * specified timeout has elapsed, or the SDLAlert is preempted</li>
- * <li>An SDLAlert will preempt (abort) any SmartDeviceLink Operation that is in-progress,
- * except an already-in-progress SDLAlert</li>
- * <li>An SDLAlert cannot be preempted by any SmartDeviceLink Operation</li>
- * <li>An SDLAlert can be preempted by a user action (button push)</li>
- * <li>An SDLAlert will fail if it is issued while another SDLAlert is in progress</li>
- * <li>Although each Alert parameter is optional, in fact each SDLAlert request
- * must supply at least one of the following parameters:<br/>
- * <ul>
- * <li>alertText1</li>
- * <li>alertText2</li>
- * <li>ttsChunks</li>
- * </ul>
- * </li>
- * </ul>
- * <br/>
- * <b>HMILevel needs to be FULL or LIMITED.</b><br/>
- * <b>If the app has been granted function group Notification the SDLHMILevel can
- * also be BACKGROUND</b><br/>
- *
- * @since SDL 1.0
- */
+ Shows an alert which typically consists of text-to-speech message and text on the display. Either `alertText1`, `alertText2` or `TTSChunks` needs to be set or the request will be rejected.
-NS_ASSUME_NONNULL_BEGIN
+ If connecting to SDL Core v.6.0+, the alert can be canceled programmatically using the `cancelID`. Canceling will not dismiss the alert's speech - only the modal view will be dismissed. On older versions of SDL Core, the alert will persist until the user has interacted with the alert or the specified timeout has elapsed.
+ @since SDL 1.0
+ */
@interface SDLAlert : SDLRPCRequest
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
+/**
+ Convenience init for creating a modal view with text, buttons, and optional sound cues.
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 __deprecated_msg("Use initWithAlertText1:alertText2: instead");
+ @param alertText The string to be displayed in the first field of the display
+ @param softButtons Soft buttons to be displayed
+ @param playTone Whether the alert tone should be played before the TTS (if any) is spoken
+ @param ttsChunks Speech or a sound file to be played when the alert shows
+ @param cancelID An ID for this specific alert to allow cancellation through the `CancelInteraction` RPC
+ @param icon Image to be displayed in the alert
+ @return An SDLAlert object
+ */
+- (instancetype)initWithAlertText:(nullable NSString *)alertText softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons playTone:(BOOL)playTone ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertIcon:(nullable SDLImage *)icon cancelID:(UInt32)cancelID;
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
+/**
+ Convenience init for creating a sound-only alert.
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2: instead");
+ @param ttsChunks Speech or a sound file to be played when the alert shows
+ @param playTone Whether the alert tone should be played before the TTS is spoken
+ @return An SDLAlert object
+ */
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone;
-- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 playTone:(BOOL)playTone duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
+/**
+ Convenience init for setting all alert parameters.
-- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param alertText3 The third line of the alert
+ @param softButtons Buttons for the alert
+ @param playTone Whether the alert tone should be played before the TTS (if any) is spoken
+ @param ttsChunks An array of text chunks to be spoken or a prerecorded sound file
+ @param duration The duration of the displayed portion of the alert, in milliseconds
+ @param progressIndicator Whether an animation indicating that loading of a feature is progressing should be shown
+ @param cancelID An ID for this specific alert to allow cancellation through the `CancelInteraction` RPC
+ @param icon Image to be displayed in the alert
+ @return An SDLAlert object
+ */
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons playTone:(BOOL)playTone ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks duration:(UInt16)duration progressIndicator:(BOOL)progressIndicator alertIcon:(nullable SDLImage *)icon cancelID:(UInt32)cancelID;
-- (instancetype)initWithTTS:(nullable NSString *)ttsText playTone:(BOOL)playTone __deprecated_msg("Use initWithTTSChunks:playTone: instead");
+/**
+ Convenience init for creating an alert with two lines of text and a timeout.
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:ttsChunks:playTone:progressIndicator:duration:softButtons:alertIcon: instead");
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param duration The duration of the displayed portion of the alert, in milliseconds
+ @return An SDLAlert object
+ */
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:ttsChunks:playTone:progressIndicator:duration:softButtons:alertIcon: instead");;
+/**
+ Convenience init for creating an alert with three lines of text.
-- (instancetype)initWithAlertText1:(NSString *)alertText1 alertText2:(nullable NSString *)alertText2;
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param alertText3 The third line of the alert
+ @return An SDLAlert object
+ */
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone;
+/**
+ Convenience init for creating an alert with three lines of text and a timeout.
+
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param alertText3 The third line of the alert
+ @param duration The duration of the displayed portion of the alert, in milliseconds
+ @return An SDLAlert object
+ */
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
+
+/**
+ Convenience init for creating an alert with three lines of text and a timeout.
+
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param alertText3 The third line of the alert
+ @param duration The duration of the displayed portion of the alert, in milliseconds
+ @param softButtons Buttons for the alert
+ @return An SDLAlert object
+ */
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
+
+/**
+ Convenience init for creating a speech-only alert.
+
+ @param ttsText Speech to be played
+ @param playTone Whether the alert tone should be played before the TTS is spoken
+ @return An SDLAlert object
+ */
+- (instancetype)initWithTTS:(nullable NSString *)ttsText playTone:(BOOL)playTone __deprecated_msg("Use initWithTTS:playTone: instead");
+
+/**
+ Convenience init for creating an alert with two lines of text, optional sound cues, and a timout.
+
+ @param ttsText Speech to be played
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param playTone Whether the alert tone should be played before the TTS is spoken
+ @param duration The duration of the displayed portion of the alert, in milliseconds
+ @return An SDLAlert object
+ */
+- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 playTone:(BOOL)playTone duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
+
+/**
+ Convenience init for creating an alert with three lines of text, optional sound cues, and a timout.
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone progressIndicator:(BOOL)showProgressIndicator duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons alertIcon:(nullable SDLImage *)icon;
+ @param ttsText Speech to be played
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param alertText3 The third line of the alert
+ @param playTone Whether the alert tone should be played before the TTS is spoken
+ @param duration The duration of the displayed portion of the alert, in milliseconds
+ @return An SDLAlert object
+ */
+- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
/**
- * The String to be displayed in the first field of the display during the Alert
- *
- * @discussion Length is limited to what is indicated in *SDLRegisterAppInterface* response
- *
- * If omitted, top display line will be cleared
- *
- * Text is always centered
- *
- * Optional, Max length 500 chars
+ Convenience init for creating an alert with three lines of text, soft buttons, and optional sound cues.
+
+ @param ttsChunks Speech or a sound file to be played when the alert shows
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param alertText3 The third line of the alert
+ @param playTone Whether the alert tone should be played before the TTS is spoken
+ @param softButtons Buttons for the alert
+ @return An SDLAlert object
+ */
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
+
+/**
+ Convenience init for creating an alert with three lines of text, soft buttons, optional sound cues, and a timout.
+
+ @param ttsChunks Speech or a sound file to be played when the alert shows
+ @param alertText1 The first line of the alert
+ @param alertText2 The second line of the alert
+ @param alertText3 The third line of the alert
+ @param playTone Whether the alert tone should be played before the TTS is spoken
+ @param duration The duration of the displayed portion of the alert, in milliseconds
+ @param softButtons Buttons for the alert
+ @return An SDLAlert object
+ */
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:softButtons:playTone:ttsChunks:duration:progressIndicator:alertIcon:cancelID: instead");
+
+/**
+ The first line of the alert text field.
+
+ @discussion At least either `alertText1`, `alertText2` or `ttsChunks` need to be provided.
+ @discussion If supported, the `displayCapabilities` will have a `TextField` with a `name` of `alertText1`.
+
+ String, Optional, Max length 500 chars
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSString *alertText1;
/**
- * The String to be displayed in the second field of the display during the Alert
- *
- * @discussion Only permitted if HMI supports a second display line
- *
- * Length is limited to what is indicated in *SDLRegisterAppInterface* response
- *
- * If omitted, second display line will be cleared
- *
- * Text is always centered
- *
- * Optional, Max length 500 chars
+ The second line of the alert text field.
+
+ @discussion At least either `alertText1`, `alertText2` or `ttsChunks` need to be provided.
+ @discussion If supported, the `displayCapabilities` will have a `TextField` with a `name` of `alertText2`
+
+ String, Optional, Max length 500 chars
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSString *alertText2;
/**
- * the String to be displayed in the third field of the display during the Alert
- * @discussion Only permitted if HMI supports a third display line
- *
- * Length is limited to what is indicated in *SDLRegisterAppInterface* response
- *
- * If omitted, third display line will be cleared
- *
- * Text is always centered
- *
- * Optional, Max length 500 chars
+ The optional third line of the alert text field.
+
+ @discussion If supported, the `displayCapabilities` will have a `TextField` with a `name` of `alertText3`
+
+ String, Optional, Max length 500 chars
+ @since SDL 2.0
*/
@property (nullable, strong, nonatomic) NSString *alertText3;
/**
- * An array which, taken together, specify what is to be spoken to the user
- *
- * Optional, Array of SDLTTSChunk, Array length 1 - 100
- *
- * @see SDLTTSChunk
+ An array of text chunks to be spoken or a prerecorded sound file.
+
+ @discussion At least either `alertText1`, `alertText2` or `ttsChunks` need to be provided.
+
+ Array of SDLTTSChunk, Optional, Array length 1 - 100
+
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSArray<SDLTTSChunk *> *ttsChunks;
/**
- * The duration of the displayed portion of the alert, in milliseconds.
- *
- * @discussion After this amount of time has passed, the display fields alertText1 and alertText2 will revert to what was displayed in those fields before the alert began.
- *
- * Typical timeouts are 3 - 5 seconds
- *
- * If omitted, the timeout is set to 5 seconds
- *
- * Optional, Integer, 3000 - 10000
+ The duration of the displayed portion of the alert, in milliseconds. Typical timeouts are 3 - 5 seconds. If omitted, the timeout is set to a default of 5 seconds.
+
+ Integer, Optional, Min value: 3000, Max value: 10000
+
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSNumber<SDLInt> *duration;
/**
- * Whether the alert tone should be played before the TTS (if any) is spoken.
- *
- * @discussion If ommitted, no tone is played
- *
- * Optional, Boolean
+ Whether the alert tone should be played before the TTS (if any) is spoken. If omitted or set to false, no tone is played.
+
+ Boolean, Optional
+
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSNumber<SDLBool> *playTone;
/**
- * If supported on the given platform, the alert GUI will include some sort of animation indicating that loading of a feature is progressing. e.g. a spinning wheel or hourglass, etc.
- *
- * Optional, Boolean
- *
- * @since SmartDeviceLink 2.0
+ If supported on the given platform, the alert GUI will include some sort of animation indicating that loading of a feature is progressing (e.g. a spinning wheel or hourglass, etc.).
+
+ Boolean, Optional
+
+ @since SDL 2.0
*/
@property (nullable, strong, nonatomic) NSNumber<SDLBool> *progressIndicator;
/**
- * App defined SoftButtons.
- *
- * @discussion If omitted on supported displays, the displayed alert shall not have any SoftButtons
- *
- * Optional, Array of SDLSoftButton, Array size 0 - 4
- *
- * @see SDLSoftButton
+ Buttons for the displayed alert. If omitted on supported displays, the displayed alert shall not have any buttons.
+
+ Array of SDLSoftButton, Optional, Array size 0 - 4
+
+ @since SDL 2.0
*/
@property (nullable, strong, nonatomic) NSArray<SDLSoftButton *> *softButtons;
/**
- Image struct determining whether static or dynamic icon.
- If omitted on supported displays, no (or the default if applicable) icon should be displayed.
+ An ID for this specific alert to allow cancellation through the `CancelInteraction` RPC.
+
+ Integer, Optional
+
+ @see SDLCancelInteraction
+ @since SDL 6.0
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLInt> *cancelID;
+
+/**
+ Image to be displayed in the alert. If omitted on supported displays, no (or the default if applicable) icon should be displayed.
+
+ SDLImage, Optional
+ @since SDL 6.0
*/
@property (nullable, strong, nonatomic) SDLImage *alertIcon;
diff --git a/SmartDeviceLink/SDLAlert.m b/SmartDeviceLink/SDLAlert.m
index 31cb2cbac..041943a29 100644
--- a/SmartDeviceLink/SDLAlert.m
+++ b/SmartDeviceLink/SDLAlert.m
@@ -24,70 +24,76 @@ NS_ASSUME_NONNULL_BEGIN
}
#pragma clang diagnostic pop
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:nil playTone:NO progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
-}
+- (instancetype)initWithAlertText:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons playTone:(BOOL)playTone ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks duration:(nullable NSNumber *)duration progressIndicator:(BOOL)progressIndicator alertIcon:(nullable SDLImage *)icon cancelID:(nullable NSNumber *)cancelID {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+ self.alertText1 = alertText1;
+ self.alertText2 = alertText2;
+ self.alertText3 = alertText3;
+ self.ttsChunks = ttsChunks;
+ self.duration = duration;
+ self.playTone = @(playTone);
+ self.progressIndicator = @(progressIndicator);
+ self.softButtons = softButtons;
+ self.alertIcon = icon;
+ self.cancelID = cancelID;
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 duration:(UInt16)duration {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil ttsChunks:nil playTone:NO progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
+ return self;
+}
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons playTone:(BOOL)playTone ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks duration:(UInt16)duration progressIndicator:(BOOL)progressIndicator alertIcon:(nullable SDLImage *)icon cancelID:(UInt32)cancelID {
+ return [self initWithAlertText:alertText1 alertText2:alertText2 alertText3:alertText3 softButtons:softButtons playTone:playTone ttsChunks:ttsChunks duration:@(duration) progressIndicator:progressIndicator alertIcon:icon cancelID:@(cancelID)];
}
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:nil playTone:NO progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
+- (instancetype)initWithTTS:(nullable NSString *)ttsText playTone:(BOOL)playTone {
+ return [self initWithTTS:ttsText alertText1:nil alertText2:nil playTone:playTone duration:DefaultAlertDuration];
}
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:nil playTone:NO progressIndicator:NO duration:duration softButtons:softButtons alertIcon:nil];
+- (instancetype)initWithAlertText:(nullable NSString *)alertText softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons playTone:(BOOL)playTone ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertIcon:(nullable SDLImage *)icon cancelID:(UInt32)cancelID {
+ return [self initWithAlertText:alertText alertText2:nil alertText3:nil softButtons:softButtons playTone:playTone ttsChunks:ttsChunks duration:nil progressIndicator:false alertIcon:icon cancelID:@(cancelID)];
}
-- (instancetype)initWithTTS:(nullable NSString *)ttsText playTone:(BOOL)playTone {
- return [self initWithAlertText1:nil alertText2:nil alertText3:nil ttsChunks:[SDLTTSChunk textChunksFromString:ttsText] playTone:playTone progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 {
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 duration:DefaultAlertDuration];
}
-- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 playTone:(BOOL)playTone duration:(UInt16)duration {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil ttsChunks:[SDLTTSChunk textChunksFromString:ttsText] playTone:playTone progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 duration:(UInt16)duration {
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil duration:duration];
}
-- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:[SDLTTSChunk textChunksFromString:ttsText] playTone:playTone progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration {
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 duration:duration softButtons:nil];
}
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:ttsChunks playTone:playTone progressIndicator:NO duration:DefaultAlertDuration softButtons:softButtons alertIcon:nil];
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
+ return [self initWithTTSChunks:nil alertText1:alertText1 alertText2:alertText2 alertText3:alertText3 playTone:NO duration:duration softButtons:softButtons];
}
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:ttsChunks playTone:playTone progressIndicator:NO duration:duration softButtons:softButtons alertIcon:nil];
+- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 playTone:(BOOL)playTone duration:(UInt16)duration {
+ return [self initWithTTS:ttsText alertText1:alertText1 alertText2:alertText2 alertText3:nil playTone:playTone duration:duration];
}
-- (instancetype)initWithAlertText1:(NSString *)alertText1 alertText2:(nullable NSString *)alertText2 {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil ttsChunks:nil playTone:NO progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
+- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration {
+ NSArray *ttsChunks = [SDLTTSChunk textChunksFromString:ttsText];
+ return [self initWithTTSChunks:ttsChunks alertText1:alertText1 alertText2:alertText2 alertText3:alertText3 playTone:playTone duration:duration softButtons:nil];
}
- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone {
- return [self initWithAlertText1:nil alertText2:nil alertText3:nil ttsChunks:ttsChunks playTone:playTone progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
+ return [self initWithAlertText:nil alertText2:nil alertText3:nil softButtons:nil playTone:playTone ttsChunks:ttsChunks duration:nil progressIndicator:false alertIcon:nil cancelID:nil];
}
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone progressIndicator:(BOOL)showProgressIndicator duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons alertIcon:(nullable SDLImage *)icon {
- self = [self init];
- if (!self) {
- return nil;
- }
-
- self.ttsChunks = [ttsChunks copy];
- self.alertText1 = alertText1;
- self.alertText2 = alertText2;
- self.alertText3 = alertText3;
- self.playTone = @(playTone);
- self.progressIndicator = @(showProgressIndicator);
- self.duration = @(duration);
- self.softButtons = [softButtons copy];
- self.alertIcon = icon;
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
+ return [self initWithTTSChunks:ttsChunks alertText1:alertText1 alertText2:alertText2 alertText3:alertText3 playTone:playTone duration:DefaultAlertDuration softButtons:softButtons];
+}
- return self;
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
+ return [self initWithAlertText:alertText1 alertText2:alertText2 alertText3:alertText3 softButtons:softButtons playTone:playTone ttsChunks:ttsChunks duration:@(duration) progressIndicator:false alertIcon:nil cancelID:nil];
}
+#pragma mark - Getters and Setters
+
- (void)setAlertText1:(nullable NSString *)alertText1 {
[self.parameters sdl_setObject:alertText1 forName:SDLRPCParameterNameAlertText1];
}
@@ -160,6 +166,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_objectForName:SDLRPCParameterNameAlertIcon ofClass:SDLImage.class error:nil];
}
+- (void)setCancelID:(nullable NSNumber<SDLInt> *)cancelID {
+ [self.parameters sdl_setObject:cancelID forName:SDLRPCParameterNameCancelID];
+}
+
+- (nullable NSNumber<SDLInt> *)cancelID {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameCancelID ofClass:NSNumber.class error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLCancelInteraction.h b/SmartDeviceLink/SDLCancelInteraction.h
new file mode 100644
index 000000000..f545b2df9
--- /dev/null
+++ b/SmartDeviceLink/SDLCancelInteraction.h
@@ -0,0 +1,115 @@
+//
+// SDLCancelInteraction.h
+// SmartDeviceLink
+//
+// Created by Nicole on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCRequest.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/*
+ Used to dismiss a modal view programmatically without needing to wait for the timeout to complete. Can be used to dismiss alerts, scrollable messages, sliders, and perform interactions (i.e. pop-up menus).
+
+ @see SDLAlert, SDLScrollableMessage, SDLSlider, SDLPerformInteraction
+ */
+@interface SDLCancelInteraction : SDLRPCRequest
+
+/**
+ Convenience init for dismissing the currently presented modal view (either an alert, slider, scrollable message, or perform interation).
+
+ @param functionID The ID of the type of modal view to dismiss
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithFunctionID:(UInt32)functionID;
+
+/**
+ Convenience init for dismissing a specific view.
+
+ @param functionID The ID of the type of interaction to dismiss
+ @param cancelID The ID of the specific interaction to dismiss
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithFunctionID:(UInt32)functionID cancelID:(UInt32)cancelID;
+
+/**
+ Convenience init for dismissing an alert.
+
+ @param cancelID The ID of the specific interaction to dismiss
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithAlertCancelID:(UInt32)cancelID;
+
+/**
+ Convenience init for dismissing a slider.
+
+ @param cancelID The ID of the specific interaction to dismiss
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithSliderCancelID:(UInt32)cancelID;
+
+/**
+ Convenience init for dismissing a scrollable message.
+
+ @param cancelID The ID of the specific interaction to dismiss
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithScrollableMessageCancelID:(UInt32)cancelID;
+
+/**
+ Convenience init for dismissing a perform interaction.
+
+ @param cancelID The ID of the specific interaction to dismiss
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithPerformInteractionCancelID:(UInt32)cancelID;
+
+/**
+ Convenience init for dismissing the currently presented alert.
+
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithAlert;
+
+/**
+ Convenience init for dismissing the currently presented slider.
+
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithSlider;
+
+/**
+ Convenience init for dismissing the currently presented scrollable message.
+
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithScrollableMessage;
+
+/**
+ Convenience init for dismissing the currently presented perform interaction.
+
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithPerformInteraction;
+
+/**
+ The ID of the specific interaction to dismiss. If not set, the most recent of the RPC type set in functionID will be dismissed.
+
+ Integer, Optional
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLInt> *cancelID;
+
+/**
+ The ID of the type of interaction to dismiss.
+
+ Only values 10 (PerformInteractionID), 12 (AlertID), 25 (ScrollableMessageID), and 26 (SliderID) are permitted.
+
+ Integer, Required
+ */
+@property (strong, nonatomic) NSNumber<SDLInt> *functionID;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLCancelInteraction.m b/SmartDeviceLink/SDLCancelInteraction.m
new file mode 100644
index 000000000..31a9ae613
--- /dev/null
+++ b/SmartDeviceLink/SDLCancelInteraction.m
@@ -0,0 +1,103 @@
+//
+// SDLCancelInteraction.m
+// SmartDeviceLink
+//
+// Created by Nicole on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLCancelInteraction.h"
+
+#import "NSMutableDictionary+Store.h"
+#import "SDLFunctionID.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLRPCFunctionNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLCancelInteraction
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ if (self = [super initWithName:SDLRPCFunctionNameCancelInteraction]) {
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+
+- (instancetype)initWithFunctionID:(UInt32)functionID {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+
+ self.functionID = @(functionID);
+
+ return self;
+}
+
+- (instancetype)initWithFunctionID:(UInt32)functionID cancelID:(UInt32)cancelID {
+ self = [self initWithFunctionID:functionID];
+ if (!self) {
+ return nil;
+ }
+
+ self.cancelID = @(cancelID);
+
+ return self;
+}
+
+- (instancetype)initWithAlertCancelID:(UInt32)cancelID {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameAlert].unsignedIntValue cancelID:cancelID];
+}
+
+- (instancetype)initWithSliderCancelID:(UInt32)cancelID {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSlider].unsignedIntValue cancelID:cancelID];
+}
+
+- (instancetype)initWithScrollableMessageCancelID:(UInt32)cancelID {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameScrollableMessage].unsignedIntValue cancelID:cancelID];
+}
+
+- (instancetype)initWithPerformInteractionCancelID:(UInt32)cancelID {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction].unsignedIntValue cancelID:cancelID];
+}
+
+- (instancetype)initWithAlert {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameAlert].unsignedIntValue];
+}
+
+- (instancetype)initWithSlider {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSlider].unsignedIntValue];
+}
+
+- (instancetype)initWithScrollableMessage {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameScrollableMessage].unsignedIntValue];
+}
+
+- (instancetype)initWithPerformInteraction {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction].unsignedIntValue];
+}
+
+- (void)setCancelID:(nullable NSNumber<SDLInt> *)cancelID {
+ [self.parameters sdl_setObject:cancelID forName:SDLRPCParameterNameCancelID];
+}
+
+- (nullable NSNumber<SDLInt> *)cancelID {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameCancelID ofClass:NSNumber.class error:nil];
+}
+
+- (void)setFunctionID:(NSNumber<SDLInt> *)functionID {
+ [self.parameters sdl_setObject:functionID forName:SDLRPCParameterNameFunctionID];
+}
+
+- (NSNumber<SDLInt> *)functionID {
+ NSError *error = nil;
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameFunctionID ofClass:NSNumber.class error:&error];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLCancelInteractionResponse.h b/SmartDeviceLink/SDLCancelInteractionResponse.h
new file mode 100644
index 000000000..9a2ba5cbe
--- /dev/null
+++ b/SmartDeviceLink/SDLCancelInteractionResponse.h
@@ -0,0 +1,20 @@
+//
+// SDLCancelInteractionResponse.h
+// SmartDeviceLink
+//
+// Created by Nicole on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCResponse.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ Response to the request to dismiss a modal view. If no applicable request can be dismissed, the `resultCode` will be `IGNORED`.
+ */
+@interface SDLCancelInteractionResponse : SDLRPCResponse
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLCancelInteractionResponse.m b/SmartDeviceLink/SDLCancelInteractionResponse.m
new file mode 100644
index 000000000..325fa96f1
--- /dev/null
+++ b/SmartDeviceLink/SDLCancelInteractionResponse.m
@@ -0,0 +1,27 @@
+//
+// SDLCancelInteractionResponse.m
+// SmartDeviceLink
+//
+// Created by Nicole on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLCancelInteractionResponse.h"
+#import "SDLRPCFunctionNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLCancelInteractionResponse
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ if (self = [super initWithName:SDLRPCFunctionNameCancelInteraction]) {
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLChoiceSet.h b/SmartDeviceLink/SDLChoiceSet.h
index bb411b839..f93fbc7df 100644
--- a/SmartDeviceLink/SDLChoiceSet.h
+++ b/SmartDeviceLink/SDLChoiceSet.h
@@ -15,6 +15,11 @@
NS_ASSUME_NONNULL_BEGIN
+/**
+ Notifies the subscriber that the choice set should be cancelled.
+ */
+typedef void (^SDLChoiceSetCanceledHandler)(void);
+
typedef NS_ENUM(NSUInteger, SDLChoiceSetLayout) {
SDLChoiceSetLayoutList,
SDLChoiceSetLayoutTiles,
@@ -123,6 +128,12 @@ typedef NS_ENUM(NSUInteger, SDLChoiceSetLayout) {
*/
- (instancetype)initWithTitle:(NSString *)title delegate:(id<SDLChoiceSetDelegate>)delegate layout:(SDLChoiceSetLayout)layout timeout:(NSTimeInterval)timeout initialPrompt:(nullable NSArray<SDLTTSChunk *> *)initialPrompt timeoutPrompt:(nullable NSArray<SDLTTSChunk *> *)timeoutPrompt helpPrompt:(nullable NSArray<SDLTTSChunk *> *)helpPrompt vrHelpList:(nullable NSArray<SDLVRHelpItem *> *)helpList choices:(NSArray<SDLChoiceCell *> *)choices;
+
+/**
+ Cancels the choice set. If the choice set has not yet been sent to Core, it will not be sent. If the choice set is already presented on Core, the choice set will be immediately dismissed. Canceling an already presented choice set will only work if connected to Core versions 6.0+. On older versions of Core, the choice set will not be dismissed.
+ */
+- (void)cancel;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLChoiceSet.m b/SmartDeviceLink/SDLChoiceSet.m
index 0892e611d..45a830bcd 100644
--- a/SmartDeviceLink/SDLChoiceSet.m
+++ b/SmartDeviceLink/SDLChoiceSet.m
@@ -15,6 +15,12 @@
NS_ASSUME_NONNULL_BEGIN
+@interface SDLChoiceSet()
+
+@property (nullable, copy, nonatomic) SDLChoiceSetCanceledHandler canceledHandler;
+
+@end
+
@implementation SDLChoiceSet
static NSTimeInterval _defaultTimeout = 10.0;
@@ -105,6 +111,13 @@ static SDLChoiceSetLayout _defaultLayout = SDLChoiceSetLayoutList;
return self;
}
+#pragma mark - Cancel
+
+- (void)cancel {
+ if (self.canceledHandler == nil) { return; }
+ self.canceledHandler();
+}
+
#pragma mark - Getters / Setters
+ (NSTimeInterval)defaultTimeout {
diff --git a/SmartDeviceLink/SDLChoiceSetManager.h b/SmartDeviceLink/SDLChoiceSetManager.h
index 1c3c9c373..6dd6122d6 100644
--- a/SmartDeviceLink/SDLChoiceSetManager.h
+++ b/SmartDeviceLink/SDLChoiceSetManager.h
@@ -9,6 +9,7 @@
#import <Foundation/Foundation.h>
#import "SDLInteractionMode.h"
+#import "NSNumber+NumberType.h"
@class SDLChoiceCell;
@class SDLChoiceSet;
@@ -99,8 +100,18 @@ extern SDLChoiceManagerState *const SDLChoiceManagerStateStartupError;
@param initialText The initial text within the keyboard input field. It will disappear once the user selects the field in order to enter text
@param delegate The keyboard delegate called when the user interacts with the keyboard
+ @return A unique id that can be used to cancel this keyboard. If `null`, no keyboard was created.
*/
-- (void)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate;
+- (nullable NSNumber<SDLInt> *)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate;
+
+/**
+ Cancels the keyboard-only interface if it is currently showing. If the keyboard has not yet been sent to Core, it will not be sent.
+
+ This will only dismiss an already presented keyboard if connected to head units running SDL 6.0+.
+
+ @param cancelID The unique ID assigned to the keyboard, passed as the return value from `presentKeyboardWithInitialText:keyboardDelegate:`
+ */
+- (void)dismissKeyboardWithCancelID:(NSNumber<SDLInt> *)cancelID;
@end
diff --git a/SmartDeviceLink/SDLChoiceSetManager.m b/SmartDeviceLink/SDLChoiceSetManager.m
index 9579f7807..17b8462a9 100644
--- a/SmartDeviceLink/SDLChoiceSetManager.m
+++ b/SmartDeviceLink/SDLChoiceSetManager.m
@@ -73,11 +73,13 @@ typedef NSNumber * SDLChoiceId;
@property (strong, nonatomic, nullable) SDLAsynchronousOperation *pendingPresentOperation;
@property (assign, nonatomic) UInt16 nextChoiceId;
+@property (assign, nonatomic) UInt16 nextCancelId;
@property (assign, nonatomic, getter=isVROptional) BOOL vrOptional;
@end
UInt16 const ChoiceCellIdMin = 1;
+UInt16 const ChoiceCellCancelIdMin = 1;
@implementation SDLChoiceSetManager
@@ -96,6 +98,7 @@ UInt16 const ChoiceCellIdMin = 1;
_pendingMutablePreloadChoices = [NSMutableSet set];
_nextChoiceId = ChoiceCellIdMin;
+ _nextCancelId = ChoiceCellCancelIdMin;
_vrOptional = YES;
_keyboardConfiguration = [self sdl_defaultKeyboardConfiguration];
@@ -152,6 +155,7 @@ UInt16 const ChoiceCellIdMin = 1;
_vrOptional = YES;
_nextChoiceId = ChoiceCellIdMin;
+ _nextCancelId = ChoiceCellCancelIdMin;
}
- (void)didEnterStateCheckingVoiceOptional {
@@ -277,6 +281,7 @@ UInt16 const ChoiceCellIdMin = 1;
- (void)presentChoiceSet:(SDLChoiceSet *)choiceSet mode:(SDLInteractionMode)mode withKeyboardDelegate:(nullable id<SDLKeyboardDelegate>)delegate {
if (![self.currentState isEqualToString:SDLChoiceManagerStateReady]) { return; }
+
if (choiceSet == nil) {
SDLLogW(@"Attempted to present a nil choice set, ignoring.");
return;
@@ -299,10 +304,10 @@ UInt16 const ChoiceCellIdMin = 1;
SDLPresentChoiceSetOperation *presentOp = nil;
if (delegate == nil) {
// Non-searchable choice set
- presentOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:self.connectionManager choiceSet:self.pendingPresentationSet mode:mode keyboardProperties:nil keyboardDelegate:nil];
+ presentOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:self.connectionManager choiceSet:self.pendingPresentationSet mode:mode keyboardProperties:nil keyboardDelegate:nil cancelID:self.nextCancelId++];
} else {
// Searchable choice set
- presentOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:self.connectionManager choiceSet:self.pendingPresentationSet mode:mode keyboardProperties:self.keyboardConfiguration keyboardDelegate:delegate];
+ presentOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:self.connectionManager choiceSet:self.pendingPresentationSet mode:mode keyboardProperties:self.keyboardConfiguration keyboardDelegate:delegate cancelID:self.nextCancelId++];
}
self.pendingPresentOperation = presentOp;
@@ -323,8 +328,8 @@ UInt16 const ChoiceCellIdMin = 1;
[self.transactionQueue addOperation:presentOp];
}
-- (void)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate {
- if (![self.currentState isEqualToString:SDLChoiceManagerStateReady]) { return; }
+- (nullable NSNumber<SDLInt> *)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate {
+ if (![self.currentState isEqualToString:SDLChoiceManagerStateReady]) { return nil; }
if (self.pendingPresentationSet != nil) {
[self.pendingPresentOperation cancel];
@@ -332,8 +337,22 @@ UInt16 const ChoiceCellIdMin = 1;
}
// Present a keyboard with the choice set that we used to test VR's optional state
- self.pendingPresentOperation = [[SDLPresentKeyboardOperation alloc] initWithConnectionManager:self.connectionManager keyboardProperties:self.keyboardConfiguration initialText:initialText keyboardDelegate:delegate];
+ UInt16 keyboardCancelId = self.nextCancelId++;
+ self.pendingPresentOperation = [[SDLPresentKeyboardOperation alloc] initWithConnectionManager:self.connectionManager keyboardProperties:self.keyboardConfiguration initialText:initialText keyboardDelegate:delegate cancelID:keyboardCancelId];
[self.transactionQueue addOperation:self.pendingPresentOperation];
+ return @(keyboardCancelId);
+}
+
+- (void)dismissKeyboardWithCancelID:(NSNumber<SDLInt> *)cancelID {
+ for (SDLAsynchronousOperation *op in self.transactionQueue.operations) {
+ if (![op isKindOfClass:SDLPresentKeyboardOperation.class]) { continue; }
+
+ SDLPresentKeyboardOperation *keyboardOperation = (SDLPresentKeyboardOperation *)op;
+ if (keyboardOperation.cancelId != cancelID.unsignedShortValue) { continue; }
+
+ [keyboardOperation dismissKeyboard];
+ break;
+ }
}
#pragma mark - Choice Management Helpers
@@ -386,7 +405,7 @@ UInt16 const ChoiceCellIdMin = 1;
if (keyboardConfiguration == nil) {
_keyboardConfiguration = [self sdl_defaultKeyboardConfiguration];
} else {
- _keyboardConfiguration = [[SDLKeyboardProperties alloc] initWithLanguage:keyboardConfiguration.language layout:keyboardConfiguration.keyboardLayout keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:keyboardConfiguration.limitedCharacterList autoCompleteText:keyboardConfiguration.autoCompleteText];
+ _keyboardConfiguration = [[SDLKeyboardProperties alloc] initWithLanguage:keyboardConfiguration.language layout:keyboardConfiguration.keyboardLayout keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:keyboardConfiguration.limitedCharacterList autoCompleteText:keyboardConfiguration.autoCompleteText autoCompleteList:keyboardConfiguration.autoCompleteList];
if (keyboardConfiguration.keypressMode != SDLKeypressModeResendCurrentEntry) {
SDLLogW(@"Attempted to set a keyboard configuration with an invalid keypress mode; only .resentCurrentEntry is valid. This value will be ignored, the rest of the properties will be set.");
@@ -395,7 +414,7 @@ UInt16 const ChoiceCellIdMin = 1;
}
- (SDLKeyboardProperties *)sdl_defaultKeyboardConfiguration {
- return [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageEnUs layout:SDLKeyboardLayoutQWERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil];
+ return [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageEnUs layout:SDLKeyboardLayoutQWERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil autoCompleteList:nil];
}
#pragma mark - Getters
diff --git a/SmartDeviceLink/SDLFunctionID.m b/SmartDeviceLink/SDLFunctionID.m
index c03280dcd..69e545fa1 100644
--- a/SmartDeviceLink/SDLFunctionID.m
+++ b/SmartDeviceLink/SDLFunctionID.m
@@ -89,6 +89,7 @@ NS_ASSUME_NONNULL_BEGIN
@54: SDLRPCFunctionNameGetFile,
@55: SDLRPCFunctionNamePerformAppServiceInteraction,
@56: SDLRPCFunctionNameUnpublishAppService,
+ @57: SDLRPCFunctionNameCancelInteraction,
@58: SDLRPCFunctionNameCloseApplication,
@59: SDLRPCFunctionNameShowAppMenu,
@60: SDLRPCFunctionNameCreateWindow,
diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m
index 857c043b8..ff90d3171 100644
--- a/SmartDeviceLink/SDLLifecycleManager.m
+++ b/SmartDeviceLink/SDLLifecycleManager.m
@@ -14,7 +14,6 @@
#import "SDLAsynchronousRPCRequestOperation.h"
#import "SDLBackgroundTaskManager.h"
#import "SDLChangeRegistration.h"
-#import "SDLChoiceSetManager.h"
#import "SDLConfiguration.h"
#import "SDLConnectionManagerType.h"
#import "SDLLogMacros.h"
diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h
index ac613208a..ef19ec270 100644
--- a/SmartDeviceLink/SDLNotificationConstants.h
+++ b/SmartDeviceLink/SDLNotificationConstants.h
@@ -121,6 +121,7 @@ extern SDLNotificationName const SDLDidReceiveAddSubMenuResponse;
extern SDLNotificationName const SDLDidReceiveAlertResponse;
extern SDLNotificationName const SDLDidReceiveAlertManeuverResponse;
extern SDLNotificationName const SDLDidReceiveButtonPressResponse;
+extern SDLNotificationName const SDLDidReceiveCancelInteractionResponse;
extern SDLNotificationName const SDLDidReceiveChangeRegistrationResponse;
extern SDLNotificationName const SDLDidReceiveCloseApplicationResponse;
extern SDLNotificationName const SDLDidReceiveCreateInteractionChoiceSetResponse;
@@ -188,6 +189,7 @@ extern SDLNotificationName const SDLDidReceiveAddSubMenuRequest;
extern SDLNotificationName const SDLDidReceiveAlertRequest;
extern SDLNotificationName const SDLDidReceiveAlertManeuverRequest;
extern SDLNotificationName const SDLDidReceiveButtonPressRequest;
+extern SDLNotificationName const SDLDidReceiveCancelInteractionRequest;
extern SDLNotificationName const SDLDidReceiveChangeRegistrationRequest;
extern SDLNotificationName const SDLDidReceiveCloseApplicationRequest;
extern SDLNotificationName const SDLDidReceiveCreateInteractionChoiceSetRequest;
diff --git a/SmartDeviceLink/SDLNotificationConstants.m b/SmartDeviceLink/SDLNotificationConstants.m
index 74888f8b3..73d935c57 100644
--- a/SmartDeviceLink/SDLNotificationConstants.m
+++ b/SmartDeviceLink/SDLNotificationConstants.m
@@ -29,6 +29,7 @@ SDLNotificationName const SDLDidReceiveAddSubMenuResponse = @"com.sdl.response.a
SDLNotificationName const SDLDidReceiveAlertResponse = @"com.sdl.response.alert";
SDLNotificationName const SDLDidReceiveAlertManeuverResponse = @"com.sdl.response.alertManeuver";
SDLNotificationName const SDLDidReceiveButtonPressResponse = @"com.sdl.response.buttonPress";
+SDLNotificationName const SDLDidReceiveCancelInteractionResponse = @"com.sdl.response.cancelInteraction";
SDLNotificationName const SDLDidReceiveChangeRegistrationResponse = @"com.sdl.response.changeRegistration";
SDLNotificationName const SDLDidReceiveCloseApplicationResponse = @"com.sdl.response.closeApplication";
SDLNotificationName const SDLDidReceiveCreateInteractionChoiceSetResponse = @"com.sdl.response.createInteractionChoiceSet";
@@ -93,6 +94,7 @@ SDLNotificationName const SDLDidReceiveAddSubMenuRequest = @"com.sdl.request.add
SDLNotificationName const SDLDidReceiveAlertRequest = @"com.sdl.request.alert";
SDLNotificationName const SDLDidReceiveAlertManeuverRequest = @"com.sdl.request.alertManeuver";
SDLNotificationName const SDLDidReceiveButtonPressRequest = @"com.sdl.request.buttonPress";
+SDLNotificationName const SDLDidReceiveCancelInteractionRequest = @"com.sdl.request.cancelInteraction";
SDLNotificationName const SDLDidReceiveChangeRegistrationRequest = @"com.sdl.request.changeRegistration";
SDLNotificationName const SDLDidReceiveCloseApplicationRequest = @"com.sdl.request.closeApplication";
SDLNotificationName const SDLDidReceiveCreateWindowRequest = @"com.sdl.request.createWindow";
@@ -184,6 +186,7 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica
SDLDidReceiveAlertResponse,
SDLDidReceiveAlertManeuverResponse,
SDLDidReceiveButtonPressResponse,
+ SDLDidReceiveCancelInteractionResponse,
SDLDidReceiveChangeRegistrationResponse,
SDLDidReceiveCloseApplicationResponse,
SDLDidReceiveCreateInteractionChoiceSetResponse,
diff --git a/SmartDeviceLink/SDLNotificationDispatcher.m b/SmartDeviceLink/SDLNotificationDispatcher.m
index e6115d61c..d1fb0e63d 100644
--- a/SmartDeviceLink/SDLNotificationDispatcher.m
+++ b/SmartDeviceLink/SDLNotificationDispatcher.m
@@ -115,6 +115,10 @@ NS_ASSUME_NONNULL_BEGIN
[self postRPCResponseNotification:SDLDidReceiveButtonPressResponse response:response];
}
+- (void)onCancelInteractionResponse:(SDLCancelInteractionResponse *)response {
+ [self postRPCResponseNotification:SDLDidReceiveCancelInteractionResponse response:response];
+}
+
- (void)onChangeRegistrationResponse:(SDLChangeRegistrationResponse *)response {
[self postRPCResponseNotification:SDLDidReceiveChangeRegistrationResponse response:response];
}
@@ -365,6 +369,10 @@ NS_ASSUME_NONNULL_BEGIN
[self postRPCRequestNotification:SDLDidReceiveButtonPressRequest request:request];
}
+- (void)onCancelInteraction:(SDLCancelInteraction *)request {
+ [self postRPCRequestNotification:SDLDidReceiveCancelInteractionRequest request:request];
+}
+
- (void)onChangeRegistration:(SDLChangeRegistration *)request {
[self postRPCRequestNotification:SDLDidReceiveChangeRegistrationRequest request:request];
}
diff --git a/SmartDeviceLink/SDLPerformInteraction.h b/SmartDeviceLink/SDLPerformInteraction.h
index c8929af3b..575305682 100644
--- a/SmartDeviceLink/SDLPerformInteraction.h
+++ b/SmartDeviceLink/SDLPerformInteraction.h
@@ -1,7 +1,6 @@
// SDLPerformInteraction.h
//
-
#import "SDLRPCRequest.h"
#import "SDLInteractionMode.h"
@@ -10,88 +9,243 @@
@class SDLTTSChunk;
@class SDLVRHelpItem;
+NS_ASSUME_NONNULL_BEGIN
+
/**
- * Performs an application-initiated interaction in which the user can select a
- * {@linkplain Choice} from among the specified Choice Sets. For instance, an
- * application may use a PerformInteraction to ask a user to say the name of a
- * song to play. The user's response is only valid if it appears in the
- * specified Choice Sets and is recognized by SDL
- * <p>
- * Function Group: Base
- * <p>
- * <b>HMILevel needs to be FULL</b>
- * </p>
- *
- * Since SmartDeviceLink 1.0<br/>
- * See SDLCreateInteractionChoiceSet SDLDeleteInteractionChoiceSet
- */
+ Performs an application-initiated interaction in which the user can select a choice from the passed choice set.
-NS_ASSUME_NONNULL_BEGIN
+ There are several ways to present a choice set: as visual pop-up menu (with an optional keyboard that allows for searches), as voice-recognition (VR) only menu, or as both a VR and visual menu. It is also possible to present only the keyboard for doing searches.
+
+ A choice set can have up to 100 items, however if you are presenting a visual only menu please be aware that the OEM may choose to limit the number of presented choices when the driver is distracted (i.e. the car is moving).
+
+ A VR-only menu could be used to ask a user to say the name of a song to play. The user's response would only be valid if it appears in the specified choice set.
+ A visual popup-menu could be used to present a list of albums to the user. The user would select the album they want to play from the list of presented choices.
+ A keyboard can be used for searches. For example, the user could be asked to enter the name of a restaurant. The name can be used to search for local restaurants with the same name. When the search is completed another menu can be presented with a list of potential addresses for the destination.
+
+ If connecting to SDL Core v.6.0+, the perform interaction can be canceled programmatically using the `cancelID`. On older versions of SDL Core, the perform interaction will persist until the user has interacted with the perform interaction or the specified timeout has elapsed.
+
+ @see SDLCreateInteractionChoiceSet, SDLDeleteInteractionChoiceSet
+ @since SDL 1.0
+ */
@interface SDLPerformInteraction : SDLRPCRequest
-- (instancetype)initWithInteractionChoiceSetId:(UInt16)interactionChoiceSetId;
+/**
+ Convenience init for creating a basic display or voice-recognition menu.
-- (instancetype)initWithInteractionChoiceSetIdList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIdList;
+ @param initialText Text to be displayed first
+ @param interactionMode Indicates the method in which the user is notified and uses the interaction
+ @param interactionChoiceSetIDList List of interaction choice set IDs to use with an interaction
+ @param cancelID An ID for this specific perform interaction to allow cancellation through the `CancelInteraction` RPC
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialText:(NSString *)initialText interactionMode:(SDLInteractionMode)interactionMode interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList cancelID:(UInt32)cancelID;
-- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetID:(UInt16)interactionChoiceSetID;
+/**
+ Convenience init for setting all parameters of a display or voice-recognition menu.
+
+ @param initialText Text to be displayed first
+ @param initialPrompt The initial prompt spoken to the user at the start of an interaction
+ @param interactionMode The method in which the user is notified and uses the interaction (voice, visual or both)
+ @param interactionChoiceSetIDList List of interaction choice set IDs to use with an interaction
+ @param helpPrompt The spoken text when a user speaks "help" when the interaction is occurring
+ @param timeoutPrompt The text spoken when a VR interaction times out
+ @param timeout Timeout in milliseconds
+ @param vrHelp Suggested voice recognition help items to display on-screen during a perform interaction
+ @param interactionLayout For touchscreen interactions, the mode of how the choices are presented
+ @param cancelID An ID for this specific perform interaction to allow cancellation through the `CancelInteraction` RPC.
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialText:(NSString *)initialText initialPrompt:(nullable NSArray<SDLTTSChunk *> *)initialPrompt interactionMode:(SDLInteractionMode)interactionMode interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpPrompt:(nullable NSArray<SDLTTSChunk *> *)helpPrompt timeoutPrompt:(nullable NSArray<SDLTTSChunk *> *)timeoutPrompt timeout:(UInt16)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp interactionLayout:(nullable SDLLayoutMode)interactionLayout cancelID:(UInt32)cancelID;
-- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetID:(UInt16)interactionChoiceSetID vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp;
+/**
+ Convenience init for setting the a single visual or voice-recognition menu choice.
-- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpPrompt:(nullable NSString *)helpPrompt timeoutPrompt:(nullable NSString *)timeoutPrompt interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout;
+ @param interactionChoiceSetId Single interaction choice set ID to use with an interaction
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInteractionChoiceSetId:(UInt16)interactionChoiceSetId __deprecated_msg("Use initWithInitialText:interactionMode:interactionChoiceSetIDList:cancelID: instead");
-- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpPrompt:(nullable NSString *)helpPrompt timeoutPrompt:(nullable NSString *)timeoutPrompt interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp;
+/**
+ Convenience init for setting the a visual or voice-recognition menu choices.
-- (instancetype)initWithInitialChunks:(nullable NSArray<SDLTTSChunk *> *)initialChunks initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpChunks:(nullable NSArray<SDLTTSChunk *> *)helpChunks timeoutChunks:(nullable NSArray<SDLTTSChunk *> *)timeoutChunks interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp;
+ @param interactionChoiceSetIdList List of interaction choice set IDs to use with an interaction
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInteractionChoiceSetIdList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIdList __deprecated_msg("Use initWithInitialText:interactionMode:interactionChoiceSetIDList:cancelID: instead");
+
+/**
+ Convenience init for creating a visual or voice-recognition menu with one choice.
+
+ @param initialPrompt The initial prompt spoken to the user at the start of an interaction
+ @param initialText Text to be displayed first
+ @param interactionChoiceSetID Single interaction choice set ID to use with an interaction
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetID:(UInt16)interactionChoiceSetID __deprecated_msg("Use initWithInitialText:interactionMode:interactionChoiceSetIDList:cancelID: instead");
+
+/**
+ Convenience init for creating a visual or voice-recognition menu with one choice and VR help items.
+
+ @param initialPrompt The initial prompt spoken to the user at the start of an interaction
+ @param initialText Text to be displayed first
+ @param interactionChoiceSetID Single interaction choice set ID to use with an interaction
+ @param vrHelp Suggested voice recognition help items to display on-screen during a perform interaction
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetID:(UInt16)interactionChoiceSetID vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp __deprecated_msg("Use initWithInitialText:initialPrompt:interactionMode:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:timeout:vrHelp:interactionLayout:cancelID: instead");
+
+/**
+ Convenience init for creating a visual or voice-recognition menu using the default display layout and VR help items. Prompts are created from the passed strings.
+
+ @param initialText Text to be displayed first
+ @param initialPrompt The initial prompt spoken to the user at the start of an interaction
+ @param interactionMode The method in which the user is notified and uses the interaction (voice, visual or both)
+ @param interactionChoiceSetIDList List of interaction choice set IDs to use with an interaction
+ @param helpPrompt The spoken text when a user speaks "help" when the interaction is occurring
+ @param timeoutPrompt The text spoken when a VR interaction times out
+ @param timeout Timeout in milliseconds
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpPrompt:(nullable NSString *)helpPrompt timeoutPrompt:(nullable NSString *)timeoutPrompt interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout __deprecated_msg("Use initWithInitialText:initialPrompt:interactionMode:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:timeout:vrHelp:interactionLayout:cancelID: instead");
+
+/**
+ Convenience init for creating a visual or voice-recognition menu using the default display layout. Prompts are created from the passed strings.
+
+ @param initialText Text to be displayed first
+ @param initialPrompt The initial prompt spoken to the user at the start of an interaction
+ @param interactionMode The method in which the user is notified and uses the interaction (voice, visual or both)
+ @param interactionChoiceSetIDList List of interaction choice set IDs to use with an interaction
+ @param helpPrompt The spoken text when a user speaks "help" when the interaction is occurring
+ @param timeoutPrompt The text spoken when a VR interaction times out
+ @param timeout Timeout in milliseconds
+ @param vrHelp Suggested voice recognition help items to display on-screen during a perform interaction
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialPrompt:(nullable NSString *)initialPrompt initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpPrompt:(nullable NSString *)helpPrompt timeoutPrompt:(nullable NSString *)timeoutPrompt interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp __deprecated_msg("Use initWithInitialText:initialPrompt:interactionMode:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:timeout:vrHelp:interactionLayout:cancelID: instead");
+
+/**
+ Convenience init for creating a visual or voice-recognition menu using the default display layout.
+
+ @param initialText Text to be displayed first
+ @param initialChunks The initial prompt spoken to the user at the start of an interaction
+ @param interactionMode The method in which the user is notified and uses the interaction (voice, visual or both)
+ @param interactionChoiceSetIDList List of interaction choice set IDs to use with an interaction
+ @param helpChunks The spoken text when a user speaks "help" when the interaction is occurring
+ @param timeoutChunks The text spoken when a VR interaction times out
+ @param timeout Timeout in milliseconds
+ @param vrHelp Suggested voice recognition help items to display on-screen during a perform interaction
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialChunks:(nullable NSArray<SDLTTSChunk *> *)initialChunks initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpChunks:(nullable NSArray<SDLTTSChunk *> *)helpChunks timeoutChunks:(nullable NSArray<SDLTTSChunk *> *)timeoutChunks interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp __deprecated_msg("Use initWithInitialText:initialPrompt:interactionMode:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:timeout:vrHelp:interactionLayout:cancelID: instead");
-- (instancetype)initWithInitialChunks:(nullable NSArray<SDLTTSChunk *> *)initialChunks initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpChunks:(nullable NSArray<SDLTTSChunk *> *)helpChunks timeoutChunks:(nullable NSArray<SDLTTSChunk *> *)timeoutChunks interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp interactionLayout:(nullable SDLLayoutMode)layout;
+/**
+ Convenience init for setting all parameters of a visual or voice-recognition menu.
+
+ @param initialText Text to be displayed first
+ @param initialChunks The initial prompt spoken to the user at the start of an interaction
+ @param interactionMode The method in which the user is notified and uses the interaction (voice, visual or both)
+ @param interactionChoiceSetIDList List of interaction choice set IDs to use with an interaction
+ @param helpChunks The spoken text when a user speaks "help" when the interaction is occurring
+ @param timeoutChunks The text spoken when a VR interaction times out
+ @param timeout Timeout in milliseconds
+ @param vrHelp Suggested voice recognition help items to display on-screen during a perform interaction
+ @param layout For touchscreen interactions, the mode of how the choices are presented
+ @return An SDLPerformInteraction object
+ */
+- (instancetype)initWithInitialChunks:(nullable NSArray<SDLTTSChunk *> *)initialChunks initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpChunks:(nullable NSArray<SDLTTSChunk *> *)helpChunks timeoutChunks:(nullable NSArray<SDLTTSChunk *> *)timeoutChunks interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp interactionLayout:(nullable SDLLayoutMode)layout __deprecated_msg("Use initWithInitialText:initialPrompt:interactionMode:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:timeout:vrHelp:interactionLayout:cancelID: instead");
/**
- * The Text that Displayed when the interaction begins. This text may
- * be overlaid by the "Listening" prompt during the interaction. Text is
- * displayed on first line of multiline display, and is centered. If text
- * does not fit on line, it will be truncated
+ Text to be displayed first.
+
+ String, Required
+
+ @since SDL 1.0
*/
@property (strong, nonatomic) NSString *initialText;
+
/**
- * An array of one or more TTSChunks that, taken together, specify
- * what is to be spoken to the user at the start of an interaction
+ This is the TTS prompt spoken to the user at the start of an interaction.
+
+ Array of SDLTTSChunk, Optional, Array size: 1-100
+
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSArray<SDLTTSChunk *> *initialPrompt;
+
/**
- * The Indicates mode that indicate how user selects interaction
- * choice. User can choose either by voice (VR_ONLY), by visual selection
- * from the menu (MANUAL_ONLY), or by either mode (BOTH)
+ For application-requested interactions, this mode indicates the method in which the user is notified and uses the interaction. Users can choose either only by voice (VR_ONLY), by tactile selection from the menu (MANUAL_ONLY), or by either mode (BOTH).
+
+ SDLInteractionMode, Required
+
+ @since SDL 1.0
*/
@property (strong, nonatomic) SDLInteractionMode interactionMode;
+
/**
- * A Vector<Integer> value representing an Array of one or more Choice
- * Set IDs
+ List of interaction choice set IDs to use with an interaction.
+
+ Array of Integers, Required, Array size: 0-100, Min value: 0, Max value: 2000000000
+
+ @since SDL 1.0
*/
@property (strong, nonatomic) NSArray<NSNumber<SDLInt> *> *interactionChoiceSetIDList;
+
/**
- * A Vector<TTSChunk> which taken together, specify the help phrase to
- * be spoken when the user says "help" during the VR session
+ Help text. This is the spoken text when a user speaks "help" while the interaction is occurring.
+
+ SDLTTSChunk, Optional
+
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSArray<SDLTTSChunk *> *helpPrompt;
+
/**
- * An array of TTSChunks which, taken together, specify the phrase to
- * be spoken when the listen times out during the VR session
+ Timeout text. This text is spoken when a VR interaction times out.
+
+ Array of SDLTTSChunk, Optional, Array size: 1-100
+
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSArray<SDLTTSChunk *> *timeoutPrompt;
+
/**
- * An Integer value representing the amount of time, in milliseconds,
- * SDL will wait for the user to make a choice (VR or Menu)
+ Timeout in milliseconds. Applies only to the menu portion of the interaction. The VR timeout will be handled by the platform. If omitted a standard value of 10 seconds is used.
+
+ Integer, Optional, Min value: 5000, Max value: 100,000
+
+ @since SDL 1.0
*/
@property (nullable, strong, nonatomic) NSNumber<SDLInt> *timeout;
+
/**
- * A Voice recognition Help, which is a suggested VR Help Items to
- * display on-screen during Perform Interaction
- * @since SmartDeviceLink 2.0
+ Suggested voice recognition help items to display on-screen during a perform interaction. If omitted on supported displays, the default generated list of suggested choices shall be displayed.
+
+ SDLVRHelpItem, Optional
+
+ @since SDL 2.0
*/
@property (nullable, strong, nonatomic) NSArray<SDLVRHelpItem *> *vrHelp;
+
+/**
+ For tactile interaction modes (MANUAL_ONLY, or BOTH), the layout mode of how the choices are presented.
+
+ SDLLayoutMode, Optional
+
+ @since SDL 3.0
+ */
@property (nullable, strong, nonatomic) SDLLayoutMode interactionLayout;
+/**
+ An ID for this specific perform interaction to allow cancellation through the `CancelInteraction` RPC.
+
+ Integer, Optional
+
+ @see SDLCancelInteraction
+ @since SDL 6.0
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLInt> *cancelID;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPerformInteraction.m b/SmartDeviceLink/SDLPerformInteraction.m
index d44ac3e16..6b72bf502 100644
--- a/SmartDeviceLink/SDLPerformInteraction.m
+++ b/SmartDeviceLink/SDLPerformInteraction.m
@@ -23,6 +23,35 @@ NS_ASSUME_NONNULL_BEGIN
}
#pragma clang diagnostic pop
+- (instancetype)initWithInitialDisplayText:(NSString *)initialText initialPrompt:(nullable NSArray<SDLTTSChunk *> *)initialPrompt interactionMode:(SDLInteractionMode)interactionMode interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpPrompt:(nullable NSArray<SDLTTSChunk *> *)helpPrompt timeoutPrompt:(nullable NSArray<SDLTTSChunk *> *)timeoutPrompt timeout:(nullable NSNumber *)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp interactionLayout:(nullable SDLLayoutMode)interactionLayout cancelID:(nullable NSNumber *)cancelID {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+
+ self.initialText = initialText;
+ self.initialPrompt = initialPrompt;
+ self.interactionMode = interactionMode;
+ self.interactionChoiceSetIDList = interactionChoiceSetIDList;
+ self.helpPrompt = helpPrompt;
+ self.timeoutPrompt = timeoutPrompt;
+ self.timeout = timeout;
+ self.vrHelp = vrHelp;
+ self.interactionLayout = interactionLayout;
+ self.cancelID = cancelID;
+
+ return self;
+}
+
+- (instancetype)initWithInitialText:(NSString *)initialText interactionMode:(SDLInteractionMode)interactionMode interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList cancelID:(UInt32)cancelID {
+ return [self initWithInitialDisplayText:initialText initialPrompt:nil interactionMode:interactionMode interactionChoiceSetIDList:interactionChoiceSetIDList helpPrompt:nil timeoutPrompt:nil timeout:nil vrHelp:nil interactionLayout:nil cancelID:@(cancelID)];
+}
+
+- (instancetype)initWithInitialText:(NSString *)initialText initialPrompt:(nullable NSArray<SDLTTSChunk *> *)initialPrompt interactionMode:(SDLInteractionMode)interactionMode interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpPrompt:(nullable NSArray<SDLTTSChunk *> *)helpPrompt timeoutPrompt:(nullable NSArray<SDLTTSChunk *> *)timeoutPrompt timeout:(UInt16)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp interactionLayout:(nullable SDLLayoutMode)interactionLayout cancelID:(UInt32)cancelID {
+ return [self initWithInitialDisplayText:initialText initialPrompt:initialPrompt interactionMode:interactionMode interactionChoiceSetIDList:interactionChoiceSetIDList helpPrompt:helpPrompt timeoutPrompt:timeoutPrompt timeout:@(timeout) vrHelp:vrHelp interactionLayout:interactionLayout cancelID:@(cancelID)];
+}
+
+
- (instancetype)initWithInteractionChoiceSetId:(UInt16)interactionChoiceSetId {
return [self initWithInteractionChoiceSetIdList:@[@(interactionChoiceSetId)]];
}
@@ -45,7 +74,7 @@ NS_ASSUME_NONNULL_BEGIN
return nil;
}
- self.vrHelp = [vrHelp mutableCopy];
+ self.vrHelp = vrHelp;
return self;
}
@@ -66,21 +95,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (instancetype)initWithInitialChunks:(nullable NSArray<SDLTTSChunk *> *)initialChunks initialText:(NSString *)initialText interactionChoiceSetIDList:(NSArray<NSNumber<SDLUInt> *> *)interactionChoiceSetIDList helpChunks:(nullable NSArray<SDLTTSChunk *> *)helpChunks timeoutChunks:(nullable NSArray<SDLTTSChunk *> *)timeoutChunks interactionMode:(SDLInteractionMode)interactionMode timeout:(UInt32)timeout vrHelp:(nullable NSArray<SDLVRHelpItem *> *)vrHelp interactionLayout:(nullable SDLLayoutMode)layout {
- self = [self initWithInteractionChoiceSetIdList:interactionChoiceSetIDList];
- if (!self) {
- return nil;
- }
-
- self.initialPrompt = [initialChunks mutableCopy];
- self.initialText = initialText;
- self.helpPrompt = [helpChunks mutableCopy];
- self.timeoutPrompt = [timeoutChunks mutableCopy];
- self.interactionMode = interactionMode;
- self.timeout = @(timeout);
- self.vrHelp = [vrHelp mutableCopy];
- self.interactionLayout = layout;
-
- return self;
+ return [self initWithInitialDisplayText:initialText initialPrompt:initialChunks interactionMode:interactionMode interactionChoiceSetIDList:interactionChoiceSetIDList helpPrompt:helpChunks timeoutPrompt:timeoutChunks timeout:@(timeout) vrHelp:vrHelp interactionLayout:layout cancelID:nil];
}
- (instancetype)initWithInteractionChoiceSetIdList:(NSArray<NSNumber<SDLInt> *> *)interactionChoiceSetIdList {
@@ -89,7 +104,7 @@ NS_ASSUME_NONNULL_BEGIN
return nil;
}
- self.interactionChoiceSetIDList = [interactionChoiceSetIdList mutableCopy];
+ self.interactionChoiceSetIDList = interactionChoiceSetIdList;
return self;
}
@@ -169,6 +184,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_enumForName:SDLRPCParameterNameInteractionLayout error:nil];
}
+- (void)setCancelID:(nullable NSNumber<SDLInt> *)cancelID {
+ [self.parameters sdl_setObject:cancelID forName:SDLRPCParameterNameCancelID];
+}
+
+- (nullable NSNumber<SDLInt> *)cancelID {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameCancelID ofClass:NSNumber.class error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPresentChoiceSetOperation.h b/SmartDeviceLink/SDLPresentChoiceSetOperation.h
index cf92f51b0..df82bfa22 100644
--- a/SmartDeviceLink/SDLPresentChoiceSetOperation.h
+++ b/SmartDeviceLink/SDLPresentChoiceSetOperation.h
@@ -23,12 +23,38 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPresentChoiceSetOperation : SDLAsynchronousOperation
+/**
+ The choice set to be displayed.
+ */
@property (strong, nonatomic, readonly) SDLChoiceSet *choiceSet;
+
+/**
+ The choice set item the user selected.
+ */
@property (strong, nonatomic, readonly, nullable) SDLChoiceCell *selectedCell;
+
+/**
+ How the user selected the choice set item: either from the menu or through voice-recognition.
+ */
@property (strong, nonatomic, readonly, nullable) SDLTriggerSource selectedTriggerSource;
+
+/**
+ The row number of the choice set item the user selected.
+ */
@property (assign, nonatomic, readonly) NSUInteger selectedCellRow;
-- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager choiceSet:(SDLChoiceSet *)choiceSet mode:(SDLInteractionMode)mode keyboardProperties:(nullable SDLKeyboardProperties *)originalKeyboardProperties keyboardDelegate:(nullable id<SDLKeyboardDelegate>)keyboardDelegate;
+/**
+ An operation to present a choice set.
+
+ @param connectionManager The connection manager
+ @param choiceSet The choice set to be displayed
+ @param mode If the set should be presented for the user to interact via voice, touch, or both
+ @param originalKeyboardProperties The keyboard configuration
+ @param keyboardDelegate The keyboard delegate called when the user interacts with the keyboard
+ @param cancelID A unique ID for this specific choice set that allows cancellation through the `CancelInteraction` RPC.
+ @return A SDLPresentChoiceSetOperation object
+ */
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager choiceSet:(SDLChoiceSet *)choiceSet mode:(SDLInteractionMode)mode keyboardProperties:(nullable SDLKeyboardProperties *)originalKeyboardProperties keyboardDelegate:(nullable id<SDLKeyboardDelegate>)keyboardDelegate cancelID:(UInt16)cancelID;
@end
diff --git a/SmartDeviceLink/SDLPresentChoiceSetOperation.m b/SmartDeviceLink/SDLPresentChoiceSetOperation.m
index 87caf9d0a..9d60af3bf 100644
--- a/SmartDeviceLink/SDLPresentChoiceSetOperation.m
+++ b/SmartDeviceLink/SDLPresentChoiceSetOperation.m
@@ -8,10 +8,12 @@
#import "SDLPresentChoiceSetOperation.h"
+#import "SDLCancelInteraction.h"
#import "SDLChoiceCell.h"
#import "SDLChoiceSet.h"
#import "SDLChoiceSetDelegate.h"
#import "SDLConnectionManagerType.h"
+#import "SDLGlobals.h"
#import "SDLKeyboardDelegate.h"
#import "SDLKeyboardProperties.h"
#import "SDLLogMacros.h"
@@ -21,6 +23,7 @@
#import "SDLPerformInteractionResponse.h"
#import "SDLRPCNotificationNotification.h"
#import "SDLSetGlobalProperties.h"
+#import "SDLVersion.h"
NS_ASSUME_NONNULL_BEGIN
@@ -30,6 +33,13 @@ NS_ASSUME_NONNULL_BEGIN
@end
+@interface SDLChoiceSet()
+
+@property (copy, nonatomic) SDLChoiceSetCanceledHandler canceledHandler;
+
+
+@end
+
@interface SDLPresentChoiceSetOperation()
@property (strong, nonatomic) NSUUID *operationId;
@@ -43,6 +53,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic, readonly) SDLPerformInteraction *performInteraction;
@property (strong, nonatomic, readonly) SDLLayoutMode layoutMode;
@property (strong, nonatomic, readonly) NSArray<NSNumber<SDLInt> *> *choiceIds;
+@property (assign, nonatomic) UInt16 cancelId;
@property (assign, nonatomic) BOOL updatedKeyboardProperties;
@property (copy, nonatomic, nullable) NSError *internalError;
@@ -54,18 +65,25 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLPresentChoiceSetOperation
-- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager choiceSet:(SDLChoiceSet *)choiceSet mode:(SDLInteractionMode)mode keyboardProperties:(nullable SDLKeyboardProperties *)originalKeyboardProperties keyboardDelegate:(nullable id<SDLKeyboardDelegate>)keyboardDelegate {
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager choiceSet:(SDLChoiceSet *)choiceSet mode:(SDLInteractionMode)mode keyboardProperties:(nullable SDLKeyboardProperties *)originalKeyboardProperties keyboardDelegate:(nullable id<SDLKeyboardDelegate>)keyboardDelegate cancelID:(UInt16)cancelID {
self = [super init];
if (!self) { return self; }
_connectionManager = connectionManager;
_choiceSet = choiceSet;
+
+ __weak typeof(self) weakSelf = self;
+ self.choiceSet.canceledHandler = ^{
+ [weakSelf sdl_cancelInteraction];
+ };
+
_presentationMode = mode;
_operationId = [NSUUID UUID];
_originalKeyboardProperties = originalKeyboardProperties;
_keyboardProperties = originalKeyboardProperties;
_keyboardDelegate = keyboardDelegate;
+ _cancelId = cancelID;
_selectedCellRow = NSNotFound;
@@ -81,6 +99,11 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)sdl_start {
+ if (self.isCancelled) {
+ [self finishOperation];
+ return;
+ }
+
// Check if we're using a keyboard (searchable) choice set and setup keyboard properties if we need to
if (self.keyboardDelegate != nil && [self.keyboardDelegate respondsToSelector:@selector(customKeyboardConfiguration)]) {
SDLKeyboardProperties *customProperties = self.keyboardDelegate.customKeyboardConfiguration;
@@ -157,6 +180,41 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
+/**
+ * Cancels the choice set. If the choice set has not yet been sent to Core, it will not be sent. If the choice set is already presented on Core, the choice set will be immediately dismissed. Canceling an already presented choice set will only work if connected to Core versions 6.0+. On older versions of Core, the choice set will not be dismissed.
+ */
+- (void)sdl_cancelInteraction {
+ if (self.isFinished) {
+ SDLLogW(@"This operation has already finished so it can not be canceled.");
+ return;
+ } else if (self.isCancelled) {
+ SDLLogW(@"This operation has already been canceled. It will be finished at some point during the operation.");
+ return;
+ } else if (self.isExecuting) {
+ if ([SDLGlobals.sharedGlobals.rpcVersion isLessThanVersion:[[SDLVersion alloc] initWithMajor:6 minor:0 patch:0]]) {
+ SDLLogE(@"Canceling a choice set is not supported on this head unit");
+ return;
+ }
+
+ SDLLogD(@"Canceling the presented choice set interaction");
+
+ SDLCancelInteraction *cancelInteraction = [[SDLCancelInteraction alloc] initWithPerformInteractionCancelID:self.cancelId];
+
+ __weak typeof(self) weakSelf = self;
+ [self.connectionManager sendConnectionRequest:cancelInteraction withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ if (error != nil) {
+ weakSelf.internalError = error;
+ SDLLogE(@"Error canceling the presented choice set: %@, with error: %@", request, error);
+ return;
+ }
+ SDLLogD(@"The presented choice set was canceled successfully");
+ }];
+ } else {
+ SDLLogD(@"Canceling a choice set that has not yet been sent to Core");
+ [self cancel];
+ }
+}
+
#pragma mark - Getters
- (SDLPerformInteraction *)performInteraction {
@@ -170,6 +228,7 @@ NS_ASSUME_NONNULL_BEGIN
performInteraction.timeout = @((NSUInteger)(self.choiceSet.timeout * 1000));
performInteraction.interactionLayout = self.layoutMode;
performInteraction.interactionChoiceSetIDList = self.choiceIds;
+ performInteraction.cancelID = @(self.cancelId);
return performInteraction;
}
diff --git a/SmartDeviceLink/SDLPresentKeyboardOperation.h b/SmartDeviceLink/SDLPresentKeyboardOperation.h
index 754260a53..9a5a6cfb5 100644
--- a/SmartDeviceLink/SDLPresentKeyboardOperation.h
+++ b/SmartDeviceLink/SDLPresentKeyboardOperation.h
@@ -7,6 +7,7 @@
//
#import "SDLAsynchronousOperation.h"
+#import "NSNumber+NumberType.h"
@class SDLKeyboardProperties;
@@ -17,7 +18,29 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPresentKeyboardOperation : SDLAsynchronousOperation
-- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager keyboardProperties:(SDLKeyboardProperties *)originalKeyboardProperties initialText:(NSString *)initialText keyboardDelegate:(id<SDLKeyboardDelegate>)keyboardDelegate;
+/**
+ A unique ID that can be used to cancel this keyboard.
+ */
+@property (assign, nonatomic, readonly) UInt16 cancelId;
+
+/**
+ An operation to present a keyboard.
+
+ @param connectionManager The connection manager
+ @param originalKeyboardProperties The keyboard configuration
+ @param initialText The initial text within the keyboard input field. It will disappear once the user selects the field in order to enter text
+ @param keyboardDelegate The keyboard delegate called when the user interacts with the keyboard
+ @param cancelID An ID for this specific keyboard to allow cancellation through the `CancelInteraction` RPC.
+ @return A SDLPresentKeyboardOperation object
+ */
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager keyboardProperties:(SDLKeyboardProperties *)originalKeyboardProperties initialText:(NSString *)initialText keyboardDelegate:(id<SDLKeyboardDelegate>)keyboardDelegate cancelID:(UInt16)cancelID;
+
+/**
+ Cancels the keyboard-only interface if it is currently showing. If the keyboard has not yet been sent to Core, it will not be sent.
+
+ This will only dismiss an already presented keyboard if connected to head units running SDL 6.0+.
+ */
+- (void)dismissKeyboard;
@end
diff --git a/SmartDeviceLink/SDLPresentKeyboardOperation.m b/SmartDeviceLink/SDLPresentKeyboardOperation.m
index b54f040fe..8136098ba 100644
--- a/SmartDeviceLink/SDLPresentKeyboardOperation.m
+++ b/SmartDeviceLink/SDLPresentKeyboardOperation.m
@@ -8,7 +8,9 @@
#import "SDLPresentKeyboardOperation.h"
+#import "SDLCancelInteraction.h"
#import "SDLConnectionManagerType.h"
+#import "SDLGlobals.h"
#import "SDLKeyboardDelegate.h"
#import "SDLKeyboardProperties.h"
#import "SDLLogMacros.h"
@@ -18,6 +20,7 @@
#import "SDLPerformInteractionResponse.h"
#import "SDLRPCNotificationNotification.h"
#import "SDLSetGlobalProperties.h"
+#import "SDLVersion.h"
NS_ASSUME_NONNULL_BEGIN
@@ -29,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (copy, nonatomic) NSString *initialText;
@property (strong, nonatomic) SDLKeyboardProperties *originalKeyboardProperties;
@property (strong, nonatomic) SDLKeyboardProperties *keyboardProperties;
+@property (assign, nonatomic, readwrite) UInt16 cancelId;
@property (strong, nonatomic, readonly) SDLPerformInteraction *performInteraction;
@@ -38,7 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLPresentKeyboardOperation
-- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager keyboardProperties:(SDLKeyboardProperties *)originalKeyboardProperties initialText:(NSString *)initialText keyboardDelegate:(id<SDLKeyboardDelegate>)keyboardDelegate {
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager keyboardProperties:(SDLKeyboardProperties *)originalKeyboardProperties initialText:(NSString *)initialText keyboardDelegate:(id<SDLKeyboardDelegate>)keyboardDelegate cancelID:(UInt16)cancelID {
self = [super init];
if (!self) { return self; }
@@ -47,6 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
_keyboardDelegate = keyboardDelegate;
_originalKeyboardProperties = originalKeyboardProperties;
_keyboardProperties = originalKeyboardProperties;
+ _cancelId = cancelID;
_operationId = [NSUUID UUID];
return self;
@@ -110,6 +115,38 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
+- (void)dismissKeyboard {
+ if (self.isFinished) {
+ SDLLogW(@"This operation has already finished so it can not be canceled.");
+ return;
+ } else if (self.isCancelled) {
+ SDLLogW(@"This operation has already been canceled. It will be finished at some point during the operation.");
+ return;
+ } else if (self.isExecuting) {
+ if ([SDLGlobals.sharedGlobals.rpcVersion isLessThanVersion:[[SDLVersion alloc] initWithMajor:6 minor:0 patch:0]]) {
+ SDLLogE(@"Canceling a keyboard is not supported on this head unit");
+ return;
+ }
+
+ SDLLogD(@"Canceling the presented keyboard");
+
+ SDLCancelInteraction *cancelInteraction = [[SDLCancelInteraction alloc] initWithPerformInteractionCancelID:self.cancelId];
+
+ __weak typeof(self) weakSelf = self;
+ [self.connectionManager sendConnectionRequest:cancelInteraction withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ if (error != nil) {
+ weakSelf.internalError = error;
+ SDLLogE(@"Error canceling the keyboard: %@, with error: %@", request, error);
+ return;
+ }
+ SDLLogD(@"The presented keyboard was canceled successfully");
+ }];
+ } else {
+ SDLLogD(@"Canceling a keyboard that has not yet been sent to Core");
+ [self cancel];
+ }
+}
+
#pragma mark - Private Getters / Setters
- (SDLPerformInteraction *)performInteraction {
@@ -118,6 +155,7 @@ NS_ASSUME_NONNULL_BEGIN
performInteraction.interactionMode = SDLInteractionModeManualOnly;
performInteraction.interactionChoiceSetIDList = @[];
performInteraction.interactionLayout = SDLLayoutModeKeyboard;
+ performInteraction.cancelID = @(self.cancelId);
return performInteraction;
}
diff --git a/SmartDeviceLink/SDLProxyListener.h b/SmartDeviceLink/SDLProxyListener.h
index ebdbddeff..25d52f589 100644
--- a/SmartDeviceLink/SDLProxyListener.h
+++ b/SmartDeviceLink/SDLProxyListener.h
@@ -13,6 +13,8 @@
@class SDLAlertResponse;
@class SDLButtonPress;
@class SDLButtonPressResponse;
+@class SDLCancelInteraction;
+@class SDLCancelInteractionResponse;
@class SDLChangeRegistration;
@class SDLChangeRegistrationResponse;
@class SDLCloseApplication;
@@ -219,6 +221,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onButtonPressResponse:(SDLButtonPressResponse *)response;
/**
+ * Called when a `CancelInteraction` response is received from Core
+ *
+ * @param response A SDLCancelInteractionResponse object
+ */
+- (void)onCancelInteractionResponse:(SDLCancelInteractionResponse *)response;
+
+/**
* Called when a Change Registration Response is received from Core
*
* @param response A SDLChangeRegistrationResponse object
@@ -662,6 +671,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onButtonPress:(SDLButtonPress *)request;
/**
+ * Called when a `CancelInteraction` request is received from Core
+ *
+ * @param request A SDLCancelInteraction object
+ */
+- (void)onCancelInteraction:(SDLCancelInteraction *)request;
+
+/**
* Called when a `ChangeRegistration` request is received from Core
*
* @param request A SDLChangeRegistration object
diff --git a/SmartDeviceLink/SDLRPCFunctionNames.h b/SmartDeviceLink/SDLRPCFunctionNames.h
index 8cb138cf9..f9dc5d5f6 100644
--- a/SmartDeviceLink/SDLRPCFunctionNames.h
+++ b/SmartDeviceLink/SDLRPCFunctionNames.h
@@ -18,6 +18,7 @@ extern SDLRPCFunctionName const SDLRPCFunctionNameAddSubMenu;
extern SDLRPCFunctionName const SDLRPCFunctionNameAlert;
extern SDLRPCFunctionName const SDLRPCFunctionNameAlertManeuver;
extern SDLRPCFunctionName const SDLRPCFunctionNameButtonPress;
+extern SDLRPCFunctionName const SDLRPCFunctionNameCancelInteraction;
extern SDLRPCFunctionName const SDLRPCFunctionNameChangeRegistration;
extern SDLRPCFunctionName const SDLRPCFunctionNameCloseApplication;
extern SDLRPCFunctionName const SDLRPCFunctionNameCreateInteractionChoiceSet;
diff --git a/SmartDeviceLink/SDLRPCFunctionNames.m b/SmartDeviceLink/SDLRPCFunctionNames.m
index 5063716a8..744922420 100644
--- a/SmartDeviceLink/SDLRPCFunctionNames.m
+++ b/SmartDeviceLink/SDLRPCFunctionNames.m
@@ -13,6 +13,7 @@ SDLRPCFunctionName const SDLRPCFunctionNameAddSubMenu = @"AddSubMenu";
SDLRPCFunctionName const SDLRPCFunctionNameAlert = @"Alert";
SDLRPCFunctionName const SDLRPCFunctionNameAlertManeuver = @"AlertManeuver";
SDLRPCFunctionName const SDLRPCFunctionNameButtonPress = @"ButtonPress";
+SDLRPCFunctionName const SDLRPCFunctionNameCancelInteraction = @"CancelInteraction";
SDLRPCFunctionName const SDLRPCFunctionNameChangeRegistration = @"ChangeRegistration";
SDLRPCFunctionName const SDLRPCFunctionNameCloseApplication = @"CloseApplication";
SDLRPCFunctionName const SDLRPCFunctionNameCreateInteractionChoiceSet = @"CreateInteractionChoiceSet";
diff --git a/SmartDeviceLink/SDLRPCParameterNames.h b/SmartDeviceLink/SDLRPCParameterNames.h
index 0e127c363..cddaef941 100644
--- a/SmartDeviceLink/SDLRPCParameterNames.h
+++ b/SmartDeviceLink/SDLRPCParameterNames.h
@@ -86,6 +86,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameButtonCapabilities;
extern SDLRPCParameterName const SDLRPCParameterNameButtonEventMode;
extern SDLRPCParameterName const SDLRPCParameterNameButtonName;
extern SDLRPCParameterName const SDLRPCParameterNameButtonPressMode;
+extern SDLRPCParameterName const SDLRPCParameterNameCancelID;
extern SDLRPCParameterName const SDLRPCParameterNameColor;
extern SDLRPCParameterName const SDLRPCParameterNameCol;
extern SDLRPCParameterName const SDLRPCParameterNameColSpan;
@@ -218,6 +219,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameFuelLevelState;
extern SDLRPCParameterName const SDLRPCParameterNameFuelMaintenanceMode;
extern SDLRPCParameterName const SDLRPCParameterNameFuelRange;
extern SDLRPCParameterName const SDLRPCParameterNameFullAppID;
+extern SDLRPCParameterName const SDLRPCParameterNameFunctionID;
extern SDLRPCParameterName const SDLRPCParameterNameGetWayPointsEnabled;
extern SDLRPCParameterName const SDLRPCParameterNameGPS;
extern SDLRPCParameterName const SDLRPCParameterNameGraphic;
diff --git a/SmartDeviceLink/SDLRPCParameterNames.m b/SmartDeviceLink/SDLRPCParameterNames.m
index 2c562168f..9da8f235e 100644
--- a/SmartDeviceLink/SDLRPCParameterNames.m
+++ b/SmartDeviceLink/SDLRPCParameterNames.m
@@ -84,6 +84,7 @@ SDLRPCParameterName const SDLRPCParameterNameButtonCapabilities = @"buttonCapabi
SDLRPCParameterName const SDLRPCParameterNameButtonEventMode = @"buttonEventMode";
SDLRPCParameterName const SDLRPCParameterNameButtonName = @"buttonName";
SDLRPCParameterName const SDLRPCParameterNameButtonPressMode = @"buttonPressMode";
+SDLRPCParameterName const SDLRPCParameterNameCancelID = @"cancelID";
SDLRPCParameterName const SDLRPCParameterNameCoolingEnabled = @"coolingEnabled";
SDLRPCParameterName const SDLRPCParameterNameCoolingEnabledAvailable = @"coolingEnabledAvailable";
SDLRPCParameterName const SDLRPCParameterNameCoolingLevel = @"coolingLevel";
@@ -213,6 +214,7 @@ SDLRPCParameterName const SDLRPCParameterNameFuelLevel = @"fuelLevel";
SDLRPCParameterName const SDLRPCParameterNameFuelLevelState = @"fuelLevel_State";
SDLRPCParameterName const SDLRPCParameterNameFuelMaintenanceMode = @"fuelMaintenanceMode";
SDLRPCParameterName const SDLRPCParameterNameFuelRange = @"fuelRange";
+SDLRPCParameterName const SDLRPCParameterNameFunctionID = @"functionID";
SDLRPCParameterName const SDLRPCParameterNameFullAppID = @"fullAppID";
SDLRPCParameterName const SDLRPCParameterNameGetWayPointsEnabled = @"getWayPointsEnabled";
SDLRPCParameterName const SDLRPCParameterNameGPS = @"gps";
diff --git a/SmartDeviceLink/SDLScreenManager.h b/SmartDeviceLink/SDLScreenManager.h
index 412f7b4f7..78724ddb3 100644
--- a/SmartDeviceLink/SDLScreenManager.h
+++ b/SmartDeviceLink/SDLScreenManager.h
@@ -8,6 +8,7 @@
#import <Foundation/Foundation.h>
+#import "NSNumber+NumberType.h"
#import "SDLInteractionMode.h"
#import "SDLMetadataType.h"
#import "SDLTextAlignment.h"
@@ -279,10 +280,21 @@ If set to `SDLDynamicMenuUpdatesModeForceOff`, menu updates will work the legacy
@param initialText The initial text within the keyboard input field. It will disappear once the user selects the field in order to enter text
@param delegate The keyboard delegate called when the user interacts with the keyboard
+ @return A unique cancelID that can be used to cancel this keyboard
*/
-- (void)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate;
+- (nullable NSNumber<SDLInt> *)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate;
+
+/**
+ Cancels the keyboard-only interface if it is currently showing. If the keyboard has not yet been sent to Core, it will not be sent.
+
+ This will only dismiss an already presented keyboard if connected to head units running SDL 6.0+.
+
+ @param cancelID The unique ID assigned to the keyboard, passed as the return value from `presentKeyboardWithInitialText:keyboardDelegate:`
+ */
+- (void)dismissKeyboardWithCancelID:(NSNumber<SDLInt> *)cancelID;
#pragma mark Menu
+
/**
Present the top-level of your application menu. This method should be called if the menu needs to be opened programmatically because the built in menu button is hidden.
*/
diff --git a/SmartDeviceLink/SDLScreenManager.m b/SmartDeviceLink/SDLScreenManager.m
index d03791ac5..5e0d418a9 100644
--- a/SmartDeviceLink/SDLScreenManager.m
+++ b/SmartDeviceLink/SDLScreenManager.m
@@ -263,8 +263,12 @@ NS_ASSUME_NONNULL_BEGIN
[self.choiceSetManager presentChoiceSet:choiceSet mode:mode withKeyboardDelegate:delegate];
}
-- (void)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate {
- [self.choiceSetManager presentKeyboardWithInitialText:initialText delegate:delegate];
+- (nullable NSNumber<SDLInt> *)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate {
+ return [self.choiceSetManager presentKeyboardWithInitialText:initialText delegate:delegate];
+}
+
+- (void)dismissKeyboardWithCancelID:(NSNumber<SDLInt> *)cancelID{
+ [self.choiceSetManager dismissKeyboardWithCancelID:cancelID];
}
#pragma mark - Menu
@@ -277,7 +281,6 @@ NS_ASSUME_NONNULL_BEGIN
return [self.menuManager openSubmenu:cell];
}
-
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLScrollableMessage.h b/SmartDeviceLink/SDLScrollableMessage.h
index 67fab47d9..f2abda1ed 100644
--- a/SmartDeviceLink/SDLScrollableMessage.h
+++ b/SmartDeviceLink/SDLScrollableMessage.h
@@ -6,50 +6,83 @@
@class SDLSoftButton;
+NS_ASSUME_NONNULL_BEGIN
+
/**
- * Creates a full screen overlay containing a large block of formatted text that
- * can be scrolled with up to 8 SoftButtons defined
- * <p>
- * Function Group: ScrollableMessage
- * <p>
- * <b>HMILevel needs to be FULL</b>
- * <p>
- */
+ Creates a full screen overlay containing a large block of formatted text that can be scrolled with buttons available.
-NS_ASSUME_NONNULL_BEGIN
+ If connecting to SDL Core v.6.0+, the scrollable message can be canceled programmatically using the `cancelID`. On older versions of SDL Core, the scrollable message will persist until the user has interacted with the scrollable message or the specified timeout has elapsed.
+ @since SDL 2.0
+ */
@interface SDLScrollableMessage : SDLRPCRequest
+/**
+ Convenience init for creating a scrolling message with text.
+
+ @param message Body of text that can include newlines and tabs
+ @return A SDLScrollableMessage object
+ */
- (instancetype)initWithMessage:(NSString *)message;
-- (instancetype)initWithMessage:(NSString *)message timeout:(UInt16)timeout softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons;
+/**
+ Convenience init for creating a scrolling message with text and buttons.
+
+ @param message Body of text that can include newlines and tabs
+ @param timeout Indicates how long of a timeout from the last action (i.e. scrolling message resets timeout)
+ @param softButtons Buttons for the displayed scrollable message
+ @param cancelID An ID for this specific scrollable message to allow cancellation through the `CancelInteraction` RPC
+ @return A SDLScrollableMessage object
+ */
+- (instancetype)initWithMessage:(NSString *)message timeout:(UInt16)timeout softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons cancelID:(UInt32)cancelID;
+
+/**
+ Convenience init for creating a scrolling message with text and buttons.
+
+ @param message Body of text that can include newlines and tabs
+ @param timeout Indicates how long of a timeout from the last action (i.e. scrolling message resets timeout)
+ @param softButtons Buttons for the displayed scrollable message
+ @return A SDLScrollableMessage object
+ */
+- (instancetype)initWithMessage:(NSString *)message timeout:(UInt16)timeout softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithMessage:timeout:softButtons:cancelID: instead");
/**
- * A Body of text that can include newlines and tabs
- * @discussion A String value representing the Body of text that can include
- * newlines and tabs
- * <p>
- * <b>Notes: </b>Maxlength=500
+ Body of text that can include newlines and tabs.
+
+ String, Required, Max length 500 chars
+
+ @since SDL 2.0
*/
@property (strong, nonatomic) NSString *scrollableMessageBody;
+
/**
- * Gets/Sets an App defined timeout. Indicates how long of a timeout in milliseconds from the
- * last action
- * @discussion An Integer value representing an App defined timeout in milliseconds
- * <p>
- * <b>Notes</b>:Minval=0; Maxval=65535;Default=30000
+ App defined timeout. Indicates how long of a timeout from the last action (i.e. scrolling message resets timeout). If not set, a default value of 30 seconds is used by Core.
+
+ Integer, Optional, Min value: 1000, Max value: 65535, Default value: 30000
+
+ @since SDL 2.0
*/
@property (nullable, strong, nonatomic) NSNumber<SDLInt> *timeout;
+
/**
- * Gets/Sets App defined SoftButtons.If omitted on supported displays, only the
- * system defined "Close" SoftButton will be displayed
- * @discussion A Vector<SoftButton> value representing App defined
- * SoftButtons
- * <p>
- * <b>Notes: </b>Minsize=0, Maxsize=8
+ Buttons for the displayed scrollable message. If omitted on supported displays, only the system defined "Close" SoftButton will be displayed.
+
+ Array of SDLSoftButton, Optional, Array size: 0-8
+
+ Since SDL 2.0
*/
@property (nullable, strong, nonatomic) NSArray<SDLSoftButton *> *softButtons;
+/**
+ An ID for this specific scrollable message to allow cancellation through the `CancelInteraction` RPC.
+
+ Integer, Optional
+
+ @see SDLCancelInteraction
+ @since SDL 6.0
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLInt> *cancelID;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLScrollableMessage.m b/SmartDeviceLink/SDLScrollableMessage.m
index 774ccb996..994becaa8 100644
--- a/SmartDeviceLink/SDLScrollableMessage.m
+++ b/SmartDeviceLink/SDLScrollableMessage.m
@@ -22,27 +22,30 @@ NS_ASSUME_NONNULL_BEGIN
}
#pragma clang diagnostic pop
-- (instancetype)initWithMessage:(NSString *)message timeout:(UInt16)timeout softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
- self = [self initWithMessage:message];
+- (instancetype)initWithScrollableMessageBody:(NSString *)message timeout:(nullable NSNumber *)timeout softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons cancelID:(nullable NSNumber *)cancelID {
+ self = [self init];
if (!self) {
return nil;
}
- self.timeout = @(timeout);
- self.softButtons = [softButtons mutableCopy];
+ self.scrollableMessageBody = message;
+ self.timeout = timeout;
+ self.softButtons = softButtons;
+ self.cancelID = cancelID;
return self;
}
-- (instancetype)initWithMessage:(NSString *)message {
- self = [self init];
- if (!self) {
- return nil;
- }
+- (instancetype)initWithMessage:(NSString *)message timeout:(UInt16)timeout softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons cancelID:(UInt32)cancelID {
+ return [self initWithScrollableMessageBody:message timeout:@(timeout) softButtons:softButtons cancelID:@(cancelID)];
+}
- self.scrollableMessageBody = message;
+- (instancetype)initWithMessage:(NSString *)message timeout:(UInt16)timeout softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
+ return [self initWithScrollableMessageBody:message timeout:@(timeout) softButtons:softButtons cancelID:nil];
+}
- return self;
+- (instancetype)initWithMessage:(NSString *)message {
+ return [self initWithScrollableMessageBody:message timeout:nil softButtons:nil cancelID:nil];
}
- (void)setScrollableMessageBody:(NSString *)scrollableMessageBody {
@@ -70,6 +73,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_objectsForName:SDLRPCParameterNameSoftButtons ofClass:SDLSoftButton.class error:nil];
}
+- (void)setCancelID:(nullable NSNumber<SDLInt> *)cancelID {
+ [self.parameters sdl_setObject:cancelID forName:SDLRPCParameterNameCancelID];
+}
+
+- (nullable NSNumber<SDLInt> *)cancelID {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameCancelID ofClass:NSNumber.class error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLSlider.h b/SmartDeviceLink/SDLSlider.h
index 2b3b187a6..13cef4c39 100644
--- a/SmartDeviceLink/SDLSlider.h
+++ b/SmartDeviceLink/SDLSlider.h
@@ -4,98 +4,123 @@
#import "SDLRPCRequest.h"
+NS_ASSUME_NONNULL_BEGIN
+
/**
- * Creates a full screen or pop-up overlay (depending on platform) with a single user controlled slider
- *
- * HMILevel needs to be FULL
- *
- * Since SmartDeviceLink 2.0
- */
+ Creates a full screen or pop-up overlay (depending on platform) with a single user controlled slider.
-NS_ASSUME_NONNULL_BEGIN
+ If connecting to SDL Core v.6.0+, the slider can be canceled programmatically using the `cancelID`. On older versions of SDL Core, the slider will persist until the user has interacted with the slider or the specified timeout has elapsed.
+ Since SDL 2.0
+ */
@interface SDLSlider : SDLRPCRequest
/**
- Create an SDLSlider with only the number of ticks and position. Note that this is not enough to get a SUCCESS response. You must supply additional data. See below for required parameters.
+ Convenience init with all parameters.
+
+ @param numTicks Number of selectable items on a horizontal axis
+ @param position Initial position of slider control
+ @param sliderHeader Text header to display
+ @param sliderFooters Text footers to display. See the `sliderFooter` documentation for how placing various numbers of footers will affect the display
+ @param timeout Indicates how long of a timeout from the last action (i.e. sliding control resets timeout)
+ @param cancelID An ID for this specific slider to allow cancellation through the `CancelInteraction` RPC.
+ @return An SDLSlider object
+ */
+- (instancetype)initWithNumTicks:(UInt8)numTicks position:(UInt8)position sliderHeader:(NSString *)sliderHeader sliderFooters:(nullable NSArray<NSString *> *)sliderFooters timeout:(UInt16)timeout cancelID:(UInt32)cancelID;
+
+/**
+ Creates a slider with only the number of ticks and position. Note that this is not enough to get a SUCCESS response. You must supply additional data. See below for required parameters.
- @param numTicks The number of ticks present on the slider.
- @param position The default starting position of the slider.
- @return An SDLSlider RPC Request.
+ @param numTicks Number of selectable items on a horizontal axis
+ @param position Initial position of slider control
+ @return An SDLSlider object
*/
- (instancetype)initWithNumTicks:(UInt8)numTicks position:(UInt8)position;
/**
- Create an SDLSlider with all required data and a static footer (or no footer).
-
- @param numTicks The number of ticks present on the slider.
- @param position The default starting position of the slider.
- @param sliderHeader The header describing the slider.
- @param sliderFooter A static footer with text, or nil for no footer.
- @param timeout The length of time in milliseconds the popup should be displayed before automatically disappearing.
- @return An SDLSlider RPC Request.
+ Creates a slider with all required data and a static footer (or no footer).
+
+ @param numTicks Number of selectable items on a horizontal axis
+ @param position Initial position of slider control
+ @param sliderHeader Text header to display
+ @param sliderFooter Text footer to display
+ @param timeout Indicates how long of a timeout from the last action (i.e. sliding control resets timeout)
+ @return An SDLSlider object
*/
- (instancetype)initWithNumTicks:(UInt8)numTicks position:(UInt8)position sliderHeader:(NSString *)sliderHeader sliderFooter:(nullable NSString *)sliderFooter timeout:(UInt16)timeout;
/**
- Create an SDLSlider with all required data and a dynamic footer (or no footer).
-
- @param numTicks The number of ticks present on the slider.
- @param position The default starting position of the slider.
- @param sliderHeader The header describing the slider.
- @param sliderFooters An array of footers. This should be the same length as `numTicks` as each footer should correspond to a tick, or no footer if nil.
- @param timeout The length of time in milliseconds the popup should be displayed before automatically disappearing.
- @return An SDLSlider RPC Request.
+ Creates an slider with all required data and a dynamic footer (or no footer).
+
+ @param numTicks Number of selectable items on a horizontal axis
+ @param position Initial position of slider control
+ @param sliderHeader Text header to display
+ @param sliderFooters Text footers to display
+ @param timeout Indicates how long of a timeout from the last action (i.e. sliding control resets timeout)
+ @return An SDLSlider object
*/
- (instancetype)initWithNumTicks:(UInt8)numTicks position:(UInt8)position sliderHeader:(NSString *)sliderHeader sliderFooters:(nullable NSArray<NSString *> *)sliderFooters timeout:(UInt16)timeout;
/**
- * Represents a number of selectable items on a horizontal axis
- *
- * Required, Integer, 2 - 26
+ Represents a number of selectable items on a horizontal axis.
+
+ Integer, Required, Min value: 2, Max Value: 26
+
+ Since SDL 2.0
*/
@property (strong, nonatomic) NSNumber<SDLInt> *numTicks;
/**
- * An Initial position of slider control
- *
- * Required, Integer, 1 - 26
+ Initial position of slider control (cannot exceed numTicks).
+
+ Integer, Required, Min Value: 1, Max Value: 26
+
+ @since SDL 2.0
*/
@property (strong, nonatomic) NSNumber<SDLInt> *position;
/**
- * A text header to display
- *
- * Required, Max length 500 chars
+ Text header to display.
+
+ String, Required, Max length 500 chars
+
+ Since SDL 2.0
*/
@property (strong, nonatomic) NSString *sliderHeader;
/**
- * A text footer to display
- *
- * @discussion For a static text footer, only one footer string shall be provided in the array.
- *
- * For a dynamic text footer, the number of footer text string in the array must match the numTicks value.
- *
- * For a dynamic text footer, text array string should correlate with potential slider position index.
- *
- * If omitted on supported displays, no footer text shall be displayed.
- *
- * Optional, Array of Strings, Array length 1 - 26, Max string length 500 chars
+ Text footer to display.
+
+ For a static text footer, only one footer string shall be provided in the array.
+ For a dynamic text footer, the number of footer text string in the array must match the numTicks value.
+ For a dynamic text footer, text array string should correlate with potential slider position index.
+ If omitted on supported displays, no footer text shall be displayed.
+
+ Array of Strings, Optional, Array length 1 - 26, Max length 500 chars
+
+ Since SDL 2.0
*/
@property (strong, nonatomic, nullable) NSArray<NSString *> *sliderFooter;
/**
- * An App defined timeout in milliseconds
- *
- * @discussion Indicates how long of a timeout from the last action (i.e. sliding control resets timeout).
- *
- * If omitted, the value is set to 10000.
- *
- * Optional, Integer, 1000 - 65535
+ App defined timeout. Indicates how long of a timeout from the last action (i.e. sliding control resets timeout). If omitted, the value is set to 10 seconds.
+
+ Integer, Optional, Min value: 1000, Max value: 65535, Default value: 10000
+
+ Since SDL 2.0
*/
@property (strong, nonatomic, nullable) NSNumber<SDLInt> *timeout;
+/**
+ An ID for this specific slider to allow cancellation through the `CancelInteraction` RPC.
+
+ Integer, Optional
+
+ @see SDLCancelInteraction
+ @since SDL 6.0
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLInt> *cancelID;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLSlider.m b/SmartDeviceLink/SDLSlider.m
index f0072c171..488b428d6 100644
--- a/SmartDeviceLink/SDLSlider.m
+++ b/SmartDeviceLink/SDLSlider.m
@@ -21,6 +21,22 @@ NS_ASSUME_NONNULL_BEGIN
}
#pragma clang diagnostic pop
+- (instancetype)initWithNumTicks:(UInt8)numTicks position:(UInt8)position sliderHeader:(NSString *)sliderHeader sliderFooters:(nullable NSArray<NSString *> *)sliderFooters timeout:(UInt16)timeout cancelID:(UInt32)cancelID {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+
+ self.numTicks = @(numTicks);
+ self.position = @(position);
+ self.sliderHeader = sliderHeader;
+ self.sliderFooter = sliderFooters;
+ self.timeout = @(timeout);
+ self.cancelID = @(cancelID);
+
+ return self;
+}
+
- (instancetype)initWithNumTicks:(UInt8)numTicks position:(UInt8)position sliderHeader:(NSString *)sliderHeader sliderFooter:(nullable NSString *)sliderFooter timeout:(UInt16)timeout {
NSArray<NSString *> *footer = nil;
if (sliderFooter != nil) {
@@ -37,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN
}
self.sliderHeader = sliderHeader;
- self.sliderFooter = [sliderFooters mutableCopy];
+ self.sliderFooter = sliderFooters;
self.timeout = @(timeout);
return self;
@@ -98,6 +114,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_objectForName:SDLRPCParameterNameTimeout ofClass:NSNumber.class error:nil];
}
+- (void)setCancelID:(nullable NSNumber<SDLInt> *)cancelID {
+ [self.parameters sdl_setObject:cancelID forName:SDLRPCParameterNameCancelID];
+}
+
+- (nullable NSNumber<SDLInt> *)cancelID {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameCancelID ofClass:NSNumber.class error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h
index 58dffc8d9..d52e58af8 100644
--- a/SmartDeviceLink/SmartDeviceLink.h
+++ b/SmartDeviceLink/SmartDeviceLink.h
@@ -24,6 +24,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLAlert.h"
#import "SDLAlertManeuver.h"
#import "SDLButtonPress.h"
+#import "SDLCancelInteraction.h"
#import "SDLChangeRegistration.h"
#import "SDLCloseApplication.h"
#import "SDLCreateInteractionChoiceSet.h"
@@ -88,6 +89,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLAlertManeuverResponse.h"
#import "SDLAlertResponse.h"
#import "SDLButtonPressResponse.h"
+#import "SDLCancelInteractionResponse.h"
#import "SDLChangeRegistrationResponse.h"
#import "SDLCloseApplicationResponse.h"
#import "SDLCreateInteractionChoiceSetResponse.h"
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetManagerSpec.m
index 813bed28c..c33e07c3d 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetManagerSpec.m
@@ -17,9 +17,12 @@
#import "SDLPreloadChoicesOperation.h"
#import "SDLPresentChoiceSetOperation.h"
#import "SDLPresentKeyboardOperation.h"
+#import "SDLGlobals.h"
#import "SDLStateMachine.h"
#import "SDLSystemContext.h"
#import "TestConnectionManager.h"
+#import "SDLVersion.h"
+
@interface SDLPresentChoiceSetOperation()
@@ -78,7 +81,7 @@ describe(@"choice set manager tests", ^{
it(@"should be in the correct startup state", ^{
expect(testManager.currentState).to(equal(SDLChoiceManagerStateShutdown));
- SDLKeyboardProperties *defaultProperties = [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageEnUs layout:SDLKeyboardLayoutQWERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil];
+ SDLKeyboardProperties *defaultProperties = [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageEnUs layout:SDLKeyboardLayoutQWERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil autoCompleteList:nil];
expect(testManager.keyboardConfiguration).to(equal(defaultProperties));
});
@@ -329,15 +332,63 @@ describe(@"choice set manager tests", ^{
pendingPresentOp = OCMClassMock([SDLPresentChoiceSetOperation class]);
testManager.pendingPresentOperation = pendingPresentOp;
testManager.pendingPresentationSet = [[SDLChoiceSet alloc] init];
-
- [testManager presentKeyboardWithInitialText:testInitialText delegate:testKeyboardDelegate];
});
- it(@"should properly start the keyboard presentation", ^{
+ it(@"should return a cancelID and should properly start the keyboard presentation with presentKeyboardWithInitialText:keyboardDelegate:", ^{
+ NSNumber *cancelID = [testManager presentKeyboardWithInitialText:testInitialText delegate:testKeyboardDelegate];
+
+ expect(cancelID).toNot(beNil());
OCMVerify([pendingPresentOp cancel]);
expect(testManager.transactionQueue.operations).to(haveCount(1));
expect(testManager.pendingPresentOperation).to(beAnInstanceOf([SDLPresentKeyboardOperation class]));
});
+
+ it(@"should return nil and should not start the keyboard presentation if the the keyboard can not be sent to Core", ^{
+ [testManager.stateMachine setToState:SDLChoiceManagerStateCheckingVoiceOptional fromOldState:SDLChoiceManagerStateShutdown callEnterTransition:NO];
+ NSNumber *cancelID = [testManager presentKeyboardWithInitialText:testInitialText delegate:testKeyboardDelegate];
+
+ expect(cancelID).to(beNil());
+ OCMReject([pendingPresentOp cancel]);
+ expect(testManager.transactionQueue.operations).to(haveCount(0));
+ expect(testManager.pendingPresentOperation).toNot(beAnInstanceOf([SDLPresentKeyboardOperation class]));
+ });
+ });
+
+ describe(@"dismissing the keyboard", ^{
+ __block SDLPresentKeyboardOperation *mockKeyboardOp1 = nil;
+ __block SDLPresentKeyboardOperation *mockKeyboardOp2 = nil;
+ __block NSOperationQueue *mockQueue = nil;
+ __block UInt16 testCancelId = 387;
+
+ beforeEach(^{
+ mockKeyboardOp1 = OCMPartialMock([[SDLPresentKeyboardOperation alloc] init]);
+ OCMStub([mockKeyboardOp1 cancelId]).andReturn(88);
+
+ mockKeyboardOp2 = OCMPartialMock([[SDLPresentKeyboardOperation alloc] init]);
+ OCMStub([mockKeyboardOp2 cancelId]).andReturn(testCancelId);
+
+ mockQueue = OCMPartialMock([[NSOperationQueue alloc] init]);
+ NSArray<SDLAsynchronousOperation *> *keyboardOps = @[mockKeyboardOp1, mockKeyboardOp2];
+ OCMStub([mockQueue operations]).andReturn(keyboardOps);
+
+ testManager.transactionQueue = mockQueue;
+ });
+
+ it(@"should dismiss the keyboard operation with the matching cancelID if it is executing", ^{
+ OCMStub([mockKeyboardOp2 isExecuting]).andReturn(true);
+ [testManager dismissKeyboardWithCancelID:@(testCancelId)];
+
+ OCMReject([mockKeyboardOp1 dismissKeyboard]);
+ OCMVerify([mockKeyboardOp2 dismissKeyboard]);
+ });
+
+ it(@"should dismiss the keyboard operation with the matching cancelID if it is not executing", ^{
+ OCMStub([mockKeyboardOp2 isExecuting]).andReturn(false);
+ [testManager dismissKeyboardWithCancelID:@(testCancelId)];
+
+ OCMReject([mockKeyboardOp1 dismissKeyboard]);
+ OCMVerify([mockKeyboardOp2 dismissKeyboard]);
+ });
});
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetSpec.m
index bce012034..76d1e4338 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLChoiceSetSpec.m
@@ -9,6 +9,12 @@
#import "SDLTTSChunk.h"
#import "SDLVrHelpItem.h"
+@interface SDLChoiceSet()
+
+@property (nullable, copy, nonatomic) SDLChoiceSetCanceledHandler canceledHandler;
+
+@end
+
QuickSpecBegin(SDLChoiceSetSpec)
describe(@"an SDLChoiceSet", ^{
@@ -27,7 +33,6 @@ describe(@"an SDLChoiceSet", ^{
testCell = [[SDLChoiceCell alloc] initWithText:@"cell text"];
testDelegate = OCMProtocolMock(@protocol(SDLChoiceSetDelegate));
testHelpItem = [[SDLVRHelpItem alloc] initWithText:@"help item" image:nil];
-
testChoiceSet = nil;
});
@@ -45,6 +50,33 @@ describe(@"an SDLChoiceSet", ^{
expect(SDLChoiceSet.defaultTimeout).to(equal(6));
});
+ it(@"should get and set correctly", ^{
+ NSArray<SDLTTSChunk *> *testTTSInitialPrompt = [SDLTTSChunk textChunksFromString:testInitialPrompt];
+ NSArray<SDLTTSChunk *> *testTTSTimeoutPrompt = [SDLTTSChunk textChunksFromString:testTimeoutPrompt];
+ NSArray<SDLTTSChunk *> *testTTSHelpPrompt = [SDLTTSChunk textChunksFromString:testHelpPrompt];
+
+ testChoiceSet = [[SDLChoiceSet alloc] init];
+ testChoiceSet.title = testTitle;
+ testChoiceSet.initialPrompt = testTTSInitialPrompt;
+ testChoiceSet.layout = testLayout;
+ testChoiceSet.timeout = testTimeout;
+ testChoiceSet.timeoutPrompt = testTTSTimeoutPrompt;
+ testChoiceSet.helpPrompt = testTTSHelpPrompt;
+ testChoiceSet.helpList = @[testHelpItem];
+ testChoiceSet.delegate = testDelegate;
+ testChoiceSet.choices = @[testCell];
+
+ expect(testChoiceSet.title).to(equal(testTitle));
+ expect(testChoiceSet.initialPrompt).to(equal(testTTSInitialPrompt));
+ expect(@(testChoiceSet.layout)).to(equal(testLayout));
+ expect(testChoiceSet.timeout).to(equal(testTimeout));
+ expect(testChoiceSet.timeoutPrompt).to(equal(testTTSTimeoutPrompt));
+ expect(testChoiceSet.helpPrompt).to(equal(testTTSHelpPrompt));
+ expect(testChoiceSet.helpList).to(equal(@[testHelpItem]));
+ expect(testChoiceSet.delegate).to(equal(testDelegate));
+ expect(testChoiceSet.choices).to(equal(@[testCell]));
+ });
+
it(@"should initialize correctly with initWithTitle:delegate:choices:", ^{
testChoiceSet = [[SDLChoiceSet alloc] initWithTitle:testTitle delegate:testDelegate choices:@[testCell]];
@@ -152,6 +184,23 @@ describe(@"an SDLChoiceSet", ^{
});
});
+ describe(@"canceling the choice set", ^{
+ __block BOOL canceledHandlerCalled = NO;
+
+ beforeEach(^{
+ testChoiceSet = [[SDLChoiceSet alloc] init];
+ testChoiceSet.canceledHandler = ^{
+ canceledHandlerCalled = YES;
+ };
+ expect(canceledHandlerCalled).to(beFalse());
+ });
+
+ it(@"should call the cancelled handler", ^{
+ [testChoiceSet cancel];
+ expect(canceledHandlerCalled).to(beTrue());
+ });
+ });
+
describe(@"setting data", ^{
beforeEach(^{
testChoiceSet = [[SDLChoiceSet alloc] init];
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m
index dda02c40d..7ca891608 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m
@@ -4,19 +4,31 @@
#import "SDLPresentChoiceSetOperation.h"
+#import "SDLCancelInteraction.h"
+#import "SDLCancelInteractionResponse.h"
#import "SDLChoiceCell.h"
#import "SDLChoiceSet.h"
#import "SDLChoiceSetDelegate.h"
+#import "SDLError.h"
+#import "SDLFunctionID.h"
#import "SDLKeyboardDelegate.h"
#import "SDLOnKeyboardInput.h"
#import "SDLKeyboardProperties.h"
#import "SDLPerformInteraction.h"
#import "SDLPerformInteractionResponse.h"
#import "SDLRPCNotificationNotification.h"
+#import "SDLGlobals.h"
#import "SDLSetGlobalProperties.h"
#import "SDLSetGlobalPropertiesResponse.h"
+#import "SDLVersion.h"
#import "TestConnectionManager.h"
+@interface SDLChoiceSet()
+
+@property (nullable, copy, nonatomic) SDLChoiceSetCanceledHandler canceledHandler;
+
+@end
+
QuickSpecBegin(SDLPresentChoiceSetOperationSpec)
describe(@"present choice operation", ^{
@@ -27,6 +39,7 @@ describe(@"present choice operation", ^{
__block SDLChoiceSet *testChoiceSet = nil;
__block id<SDLChoiceSetDelegate> testChoiceDelegate = nil;
__block NSArray<SDLChoiceCell *> *testChoices = nil;
+ __block int testCancelID = 98;
__block id<SDLKeyboardDelegate> testKeyboardDelegate = nil;
__block SDLKeyboardProperties *testKeyboardProperties = nil;
@@ -47,7 +60,7 @@ describe(@"present choice operation", ^{
testKeyboardDelegate = OCMProtocolMock(@protocol(SDLKeyboardDelegate));
OCMStub([testKeyboardDelegate customKeyboardConfiguration]).andReturn(nil);
- testKeyboardProperties = [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageArSa layout:SDLKeyboardLayoutAZERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil];
+ testKeyboardProperties = [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageArSa layout:SDLKeyboardLayoutAZERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil autoCompleteList:nil];
});
it(@"should have a priority of 'normal'", ^{
@@ -58,7 +71,7 @@ describe(@"present choice operation", ^{
describe(@"running a non-searchable choice set operation", ^{
beforeEach(^{
- testOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:testConnectionManager choiceSet:testChoiceSet mode:testInteractionMode keyboardProperties:nil keyboardDelegate:nil];
+ testOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:testConnectionManager choiceSet:testChoiceSet mode:testInteractionMode keyboardProperties:nil keyboardDelegate:nil cancelID:testCancelID];
testOp.completionBlock = ^{
hasCalledOperationCompletionHandler = YES;
};
@@ -82,6 +95,7 @@ describe(@"present choice operation", ^{
expect(request.timeout).to(equal(testChoiceSet.timeout * 1000));
expect(request.vrHelp).to(beNil());
expect(request.interactionChoiceSetIDList).to(equal(@[@65535]));
+ expect(request.cancelID).to(equal(testCancelID));
});
describe(@"after a perform interaction response", ^{
@@ -97,7 +111,6 @@ describe(@"present choice operation", ^{
[testConnectionManager respondToLastRequestWithResponse:response];
});
-
it(@"should not reset the keyboard properties and should be finished", ^{
expect(testConnectionManager.receivedRequests.lastObject).toNot(beAnInstanceOf([SDLSetGlobalProperties class]));
expect(hasCalledOperationCompletionHandler).toEventually(beTrue());
@@ -107,11 +120,200 @@ describe(@"present choice operation", ^{
});
});
});
+
+ describe(@"Canceling the choice set", ^{
+ __block SDLPresentChoiceSetOperation *testCancelOp = nil;
+
+ beforeEach(^{
+ testCancelOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:testConnectionManager choiceSet:testChoiceSet mode:testInteractionMode keyboardProperties:nil keyboardDelegate:nil cancelID:testCancelID];
+ testCancelOp.completionBlock = ^{
+ hasCalledOperationCompletionHandler = YES;
+ };
+ });
+
+ context(@"Head unit supports the `CancelInteration` RPC", ^{
+ beforeEach(^{
+ SDLVersion *supportedVersion = [SDLVersion versionWithMajor:6 minor:0 patch:0];
+ id globalMock = OCMPartialMock([SDLGlobals sharedGlobals]);
+ OCMStub([globalMock rpcVersion]).andReturn(supportedVersion);
+ });
+
+ context(@"If the operation is executing", ^{
+ beforeEach(^{
+ [testCancelOp start];
+
+ expect(testCancelOp.isExecuting).to(beTrue());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beFalse());
+
+ [testChoiceSet cancel];
+ });
+
+ it(@"should attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).to(beAnInstanceOf([SDLCancelInteraction class]));
+ expect(lastRequest.cancelID).to(equal(testCancelID));
+ expect(lastRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction]));
+ });
+
+ context(@"If the cancel interaction was successful", ^{
+ beforeEach(^{
+ SDLCancelInteractionResponse *testCancelInteractionResponse = [[SDLCancelInteractionResponse alloc] init];
+ testCancelInteractionResponse.success = @YES;
+ [testConnectionManager respondToLastRequestWithResponse:testCancelInteractionResponse];
+ });
+
+ it(@"should not error", ^{
+ expect(testCancelOp.error).to(beNil());
+ });
+
+ it(@"should not finish", ^{
+ expect(hasCalledOperationCompletionHandler).to(beFalse());
+ expect(testCancelOp.isExecuting).to(beTrue());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beFalse());
+ });
+ });
+
+ context(@"If the cancel interaction was not successful", ^{
+ __block NSError *testError = [NSError sdl_lifecycle_notConnectedError];
+
+ beforeEach(^{
+ SDLCancelInteractionResponse *testCancelInteractionResponse = [[SDLCancelInteractionResponse alloc] init];
+ testCancelInteractionResponse.success = @NO;
+ [testConnectionManager respondToLastRequestWithResponse:testCancelInteractionResponse error:testError];
+ });
+
+ it(@"should error", ^{
+ expect(testCancelOp.error).to(equal(testError));
+ });
+
+ it(@"should not finish", ^{
+ expect(hasCalledOperationCompletionHandler).to(beFalse());
+ expect(testCancelOp.isExecuting).to(beTrue());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beFalse());
+ });
+ });
+ });
+
+ context(@"If the operation has already finished", ^{
+ beforeEach(^{
+ [testCancelOp finishOperation];
+
+ expect(testCancelOp.isExecuting).to(beFalse());
+ expect(testCancelOp.isFinished).to(beTrue());
+ expect(testCancelOp.isCancelled).to(beFalse());
+
+ [testChoiceSet cancel];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+ });
+
+ context(@"If the started operation has been canceled", ^{
+ beforeEach(^{
+ [testCancelOp start];
+ [testCancelOp cancel];
+
+ expect(testCancelOp.isExecuting).to(beTrue());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beTrue());
+
+ [testChoiceSet cancel];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+
+ it(@"should not finish", ^{
+ expect(hasCalledOperationCompletionHandler).toEventually(beFalse());
+ expect(testCancelOp.isExecuting).toEventually(beTrue());
+ expect(testCancelOp.isFinished).toEventually(beFalse());
+ expect(testCancelOp.isCancelled).toEventually(beTrue());
+ });
+ });
+
+ context(@"If the operation has not started", ^{
+ beforeEach(^{
+ expect(testCancelOp.isExecuting).to(beFalse());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beFalse());
+
+ [testChoiceSet cancel];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+
+ context(@"Once the operation has started", ^{
+ beforeEach(^{
+ [testCancelOp start];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+
+ it(@"should finish", ^{
+ expect(hasCalledOperationCompletionHandler).toEventually(beTrue());
+ expect(testCancelOp.isExecuting).toEventually(beFalse());
+ expect(testCancelOp.isFinished).toEventually(beTrue());
+ expect(testCancelOp.isCancelled).toEventually(beTrue());
+ });
+ });
+ });
+ });
+
+ context(@"Head unit does not support the `CancelInteration` RPC", ^{
+ beforeEach(^{
+ SDLVersion *unsupportedVersion = [SDLVersion versionWithMajor:5 minor:1 patch:0];
+ id globalMock = OCMPartialMock([SDLGlobals sharedGlobals]);
+ OCMStub([globalMock rpcVersion]).andReturn(unsupportedVersion);
+ });
+
+ it(@"should not attempt to send a cancel interaction if the operation is executing", ^{
+ [testCancelOp start];
+
+ expect(testCancelOp.isExecuting).to(beTrue());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beFalse());
+
+ [testChoiceSet cancel];
+
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+
+ it(@"should cancel the operation if it has not yet been run", ^{
+ expect(testCancelOp.isExecuting).to(beFalse());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beFalse());
+
+ [testChoiceSet cancel];
+
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+
+ expect(testCancelOp.isExecuting).to(beFalse());
+ expect(testCancelOp.isFinished).to(beFalse());
+ expect(testCancelOp.isCancelled).to(beTrue());
+ });
+ });
+ });
});
describe(@"running a searchable choice set operation", ^{
beforeEach(^{
- testOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:testConnectionManager choiceSet:testChoiceSet mode:testInteractionMode keyboardProperties:testKeyboardProperties keyboardDelegate:testKeyboardDelegate];
+ testOp = [[SDLPresentChoiceSetOperation alloc] initWithConnectionManager:testConnectionManager choiceSet:testChoiceSet mode:testInteractionMode keyboardProperties:testKeyboardProperties keyboardDelegate:testKeyboardDelegate cancelID:testCancelID];
testOp.completionBlock = ^{
hasCalledOperationCompletionHandler = YES;
@@ -146,6 +348,7 @@ describe(@"present choice operation", ^{
expect(request.timeout).to(equal(testChoiceSet.timeout * 1000));
expect(request.vrHelp).to(beNil());
expect(request.interactionChoiceSetIDList).to(equal(@[@65535]));
+ expect(request.cancelID).to(equal(testCancelID));
});
it(@"should respond to submitted notifications", ^{
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m
index e8a5abdec..6d0b7e6cd 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m
@@ -4,15 +4,21 @@
#import "SDLPresentKeyboardOperation.h"
+#import "SDLCancelInteraction.h"
+#import "SDLCancelInteractionResponse.h"
+#import "SDLError.h"
+#import "SDLFunctionID.h"
+#import "SDLGlobals.h"
#import "SDLKeyboardDelegate.h"
-#import "SDLOnKeyboardInput.h"
#import "SDLKeyboardProperties.h"
+#import "SDLOnKeyboardInput.h"
#import "SDLPerformInteraction.h"
#import "SDLPerformInteractionResponse.h"
#import "SDLRPCNotificationNotification.h"
#import "SDLSetGlobalProperties.h"
#import "SDLSetGlobalPropertiesResponse.h"
#import "TestConnectionManager.h"
+#import "SDLVersion.h"
QuickSpecBegin(SDLPresentKeyboardOperationSpec)
@@ -23,6 +29,7 @@ describe(@"present keyboard operation", ^{
__block NSString *testInitialText = @"Initial Text";
__block id<SDLKeyboardDelegate> testDelegate = nil;
__block SDLKeyboardProperties *testInitialProperties = nil;
+ __block int testCancelID = 256;
__block BOOL hasCalledOperationCompletionHandler = NO;
__block NSError *resultError = nil;
@@ -46,7 +53,7 @@ describe(@"present keyboard operation", ^{
describe(@"running the operation", ^{
beforeEach(^{
- testOp = [[SDLPresentKeyboardOperation alloc] initWithConnectionManager:testConnectionManager keyboardProperties:testInitialProperties initialText:testInitialText keyboardDelegate:testDelegate];
+ testOp = [[SDLPresentKeyboardOperation alloc] initWithConnectionManager:testConnectionManager keyboardProperties:testInitialProperties initialText:testInitialText keyboardDelegate:testDelegate cancelID:testCancelID];
testOp.completionBlock = ^{
hasCalledOperationCompletionHandler = YES;
};
@@ -246,6 +253,202 @@ describe(@"present keyboard operation", ^{
});
});
});
+
+ describe(@"Canceling the keyboard", ^{
+ beforeEach(^{
+ testOp = [[SDLPresentKeyboardOperation alloc] initWithConnectionManager:testConnectionManager keyboardProperties:testInitialProperties initialText:testInitialText keyboardDelegate:testDelegate cancelID:testCancelID];
+ testOp.completionBlock = ^{
+ hasCalledOperationCompletionHandler = YES;
+ };
+ });
+
+ context(@"If the operation is executing", ^{
+ beforeEach(^{
+ SDLVersion *supportedVersion = [SDLVersion versionWithMajor:6 minor:0 patch:0];
+ id globalMock = OCMPartialMock([SDLGlobals sharedGlobals]);
+ OCMStub([globalMock rpcVersion]).andReturn(supportedVersion);
+
+ [testOp start];
+
+ expect(testOp.isExecuting).to(beTrue());
+ expect(testOp.isFinished).to(beFalse());
+ expect(testOp.isCancelled).to(beFalse());
+
+ [testOp dismissKeyboard];
+ });
+
+ it(@"should attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).to(beAnInstanceOf([SDLCancelInteraction class]));
+ expect(lastRequest.cancelID).to(equal(testCancelID));
+ expect(lastRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction]));
+ });
+
+ context(@"If the cancel interaction was successful", ^{
+ beforeEach(^{
+ SDLCancelInteractionResponse *testCancelInteractionResponse = [[SDLCancelInteractionResponse alloc] init];
+ testCancelInteractionResponse.success = @YES;
+ [testConnectionManager respondToLastRequestWithResponse:testCancelInteractionResponse];
+
+ SDLSetGlobalPropertiesResponse *response = [[SDLSetGlobalPropertiesResponse alloc] init];
+ response.success = @YES;
+ [testConnectionManager respondToLastRequestWithResponse:response];
+ });
+
+ it(@"should not error", ^{
+ expect(testOp.error).to(beNil());
+ });
+
+ it(@"should not finish", ^{
+ expect(hasCalledOperationCompletionHandler).to(beFalse());
+ expect(testOp.isExecuting).to(beTrue());
+ expect(testOp.isFinished).to(beFalse());
+ expect(testOp.isCancelled).to(beFalse());
+ });
+ });
+
+ context(@"If the cancel interaction was not successful", ^{
+ __block NSError *testError = [NSError sdl_lifecycle_notConnectedError];
+
+ beforeEach(^{
+ SDLCancelInteractionResponse *testCancelInteractionResponse = [[SDLCancelInteractionResponse alloc] init];
+ testCancelInteractionResponse.success = @NO;
+ [testConnectionManager respondToLastRequestWithResponse:testCancelInteractionResponse error:testError];
+
+ SDLSetGlobalPropertiesResponse *response = [[SDLSetGlobalPropertiesResponse alloc] init];
+ response.success = @YES;
+ [testConnectionManager respondToLastRequestWithResponse:response];
+ });
+
+ it(@"should error", ^{
+ expect(testOp.error).to(equal(testError));
+ });
+
+ it(@"should not finish", ^{
+ expect(hasCalledOperationCompletionHandler).toEventually(beFalse());
+ expect(testOp.isExecuting).toEventually(beTrue());
+ expect(testOp.isFinished).toEventually(beFalse());
+ expect(testOp.isCancelled).toEventually(beFalse());
+ });
+ });
+ });
+
+ context(@"The head unit does not support the `CancelInteraction` RPC", ^{
+ beforeEach(^{
+ SDLVersion *unsupportedVersion = [SDLVersion versionWithMajor:4 minor:5 patch:2];
+ id globalMock = OCMPartialMock([SDLGlobals sharedGlobals]);
+ OCMStub([globalMock rpcVersion]).andReturn(unsupportedVersion);
+ });
+
+ it(@"should not attempt to send a cancel interaction if the operation is executing", ^{
+ [testOp start];
+
+ expect(testOp.isExecuting).to(beTrue());
+ expect(testOp.isFinished).to(beFalse());
+ expect(testOp.isCancelled).to(beFalse());
+
+ [testOp dismissKeyboard];
+
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+
+ it(@"should cancel the operation if it has not yet been run", ^{
+ expect(testOp.isExecuting).to(beFalse());
+ expect(testOp.isFinished).to(beFalse());
+ expect(testOp.isCancelled).to(beFalse());
+
+ [testOp dismissKeyboard];
+
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).to(beNil());
+
+ expect(testOp.isExecuting).to(beFalse());
+ expect(testOp.isFinished).to(beFalse());
+ expect(testOp.isCancelled).to(beTrue());
+ });
+ });
+
+ context(@"If the operation has already finished", ^{
+ beforeEach(^{
+ [testOp start];
+ [testOp finishOperation];
+
+ SDLSetGlobalPropertiesResponse *response = [[SDLSetGlobalPropertiesResponse alloc] init];
+ response.success = @YES;
+ [testConnectionManager respondToLastRequestWithResponse:response];
+
+ expect(testOp.isExecuting).to(beFalse());
+ expect(testOp.isFinished).to(beTrue());
+ expect(testOp.isCancelled).to(beFalse());
+
+ [testOp dismissKeyboard];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+ });
+
+ context(@"If the started operation has been canceled", ^{
+ beforeEach(^{
+ [testOp start];
+ [testOp cancel];
+
+ expect(testOp.isExecuting).to(beTrue());
+ expect(testOp.isFinished).to(beFalse());
+ expect(testOp.isCancelled).to(beTrue());
+
+ [testOp dismissKeyboard];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+
+ it(@"should not finish", ^{
+ expect(hasCalledOperationCompletionHandler).toEventually(beFalse());
+ expect(testOp.isExecuting).toEventually(beTrue());
+ expect(testOp.isFinished).toEventually(beFalse());
+ expect(testOp.isCancelled).toEventually(beTrue());
+ });
+ });
+
+ context(@"If the operation has not started", ^{
+ beforeEach(^{
+ expect(testOp.isExecuting).to(beFalse());
+ expect(testOp.isFinished).to(beFalse());
+ expect(testOp.isCancelled).to(beFalse());
+
+ [testOp dismissKeyboard];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).to(beNil());
+ });
+
+ context(@"Once the operation has started", ^{
+ beforeEach(^{
+ [testOp start];
+ });
+
+ it(@"should not attempt to send a cancel interaction", ^{
+ SDLCancelInteraction *lastRequest = testConnectionManager.receivedRequests.lastObject;
+ expect(lastRequest).toNot(beAnInstanceOf([SDLCancelInteraction class]));
+ });
+
+ it(@"should finish", ^{
+ expect(hasCalledOperationCompletionHandler).toEventually(beTrue());
+ expect(testOp.isExecuting).toEventually(beFalse());
+ expect(testOp.isFinished).toEventually(beTrue());
+ expect(testOp.isCancelled).toEventually(beTrue());
+ });
+ });
+ });
+ });
});
QuickSpecEnd
diff --git a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m
index 410d24386..0eb289928 100644
--- a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m
+++ b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m
@@ -480,7 +480,7 @@ describe(@"a response dispatcher", ^{
__block SDLSoftButton *testSoftButton1 = nil;
beforeEach(^{
- testAlert = [[SDLAlert alloc] initWithAlertText1:@"test 1" alertText2:@"test 1" alertText3:nil duration:1 softButtons:nil];
+ testAlert = [[SDLAlert alloc] initWithAlertText1:@"test 1" alertText2:@"test 2" alertText3:nil softButtons:nil playTone:false ttsChunks:nil duration:1 progressIndicator:false alertIcon:nil cancelID:0];
testAlert.correlationID = @1;
});
@@ -591,7 +591,7 @@ describe(@"a response dispatcher", ^{
__block SDLSoftButton *testSoftButton1 = nil;
beforeEach(^{
- testScrollableMessage = [[SDLScrollableMessage alloc] initWithMessage:@"test" timeout:1 softButtons:nil];
+ testScrollableMessage = [[SDLScrollableMessage alloc] initWithMessage:@"test" timeout:1 softButtons:nil cancelID:0];
testScrollableMessage.correlationID = @1;
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m
index 22fc58cba..ec30bbbd9 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m
@@ -2,9 +2,6 @@
// SDLAlertSpec.m
// SmartDeviceLink
-
-#import <Foundation/Foundation.h>
-
#import <Quick/Quick.h>
#import <Nimble/Nimble.h>
@@ -17,310 +14,323 @@
QuickSpecBegin(SDLAlertSpec)
-SDLTTSChunk *tts = [[SDLTTSChunk alloc] init];
-SDLSoftButton *button = [[SDLSoftButton alloc] init];
-SDLImage *testImage = [[SDLImage alloc] initWithName:@"testImage" isTemplate:YES];
-
-describe(@"Alert spec", ^{
- UInt16 defaultDuration = 5000;
-
- NSString *testText1 = @"Test Text 1";
- NSString *testText2 = @"Test Text 2";
- NSString *testText3 = @"Test Text 3";
- NSString *testTTSString = @"Test TTS";
- BOOL testPlayTone = YES;
- BOOL testProgressIndicator = YES;
- UInt16 testDuration = 7847;
-
- describe(@"initializer tests", ^{
- it(@"should initialize correctly with initWithAlertText1:alertText2:duration:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 duration:testDuration];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(beNil());
- expect(testAlert.ttsChunks).to(beNil());
- expect(testAlert.duration).to(equal(testDuration));
- expect(testAlert.playTone).to(beFalse());
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
- });
+static UInt16 const SDLDefaultDuration = 5000;
+
+describe(@"Getter/Setter Tests", ^ {
+ __block SDLAlert *testRequest = nil;
+ __block NSString *testAlertText1 = @"alert#1";
+ __block NSString *testAlertText2 = @"alert#2";
+ __block NSString *testAlertText3 = @"alert#3";
+ __block int testDuration = 45;
+ __block BOOL testPlayTone = YES;
+ __block BOOL testProgressIndicator = NO;
+ __block NSArray<SDLSoftButton *> *testSoftButtons = nil;
+ __block NSArray<SDLTTSChunk *> *testTTSChunks = nil;
+ __block NSString *testTTSString = nil;
+ __block SDLImage *testImage = nil;
+ __block int testCancelID = 456;
+
+ beforeEach(^{
+ testTTSChunks = @[[[SDLTTSChunk alloc] init]];
+ testTTSString = @"Hello World";
+ testSoftButtons = @[[[SDLSoftButton alloc] init]];
+ testImage = [[SDLImage alloc] initWithStaticIconName:SDLStaticIconNameBack];
+ });
- it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(equal(testText3));
- expect(testAlert.ttsChunks).to(beNil());
- expect(testAlert.duration).to(equal(defaultDuration));
- expect(testAlert.playTone).to(beFalse());
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
- });
+ context(@"Getter/Setter Tests", ^{
+ it(@"Should set and get correctly", ^{
+ testRequest = [[SDLAlert alloc] init];
+
+ testRequest.alertText1 = testAlertText1;
+ testRequest.alertText2 = testAlertText2;
+ testRequest.alertText3 = testAlertText3;
+ testRequest.ttsChunks = testTTSChunks;
+ testRequest.duration = @(testDuration);
+ testRequest.playTone = @(testPlayTone);
+ testRequest.progressIndicator = @(testProgressIndicator);
+ testRequest.softButtons = testSoftButtons;
+ testRequest.alertIcon = testImage;
+ testRequest.cancelID = @(testCancelID);
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(equal(testTTSChunks));
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(equal(testProgressIndicator));
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.alertIcon).to(equal(testImage));
+ expect(testRequest.cancelID).to(equal(testCancelID));
- it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:duration:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3 duration:testDuration];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(equal(testText3));
- expect(testAlert.ttsChunks).to(beNil());
- expect(testAlert.duration).to(equal(testDuration));
- expect(testAlert.playTone).to(beFalse());
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
+ expect(testRequest.parameters.count).to(equal(10));
});
- it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:duration:softButtons:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3 duration:testDuration softButtons:@[button]];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(equal(testText3));
- expect(testAlert.ttsChunks).to(beNil());
- expect(testAlert.duration).to(equal(testDuration));
- expect(testAlert.playTone).to(beFalse());
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(haveCount(1));
- expect(testAlert.alertIcon).to(beNil());
- });
+ it(@"Should return nil if not set", ^{
+ testRequest = [[SDLAlert alloc] init];
- it(@"should initialize correctly with initWithTTS:alertText1:alertText2:playTone:duration:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithTTS:testTTSString alertText1:testText1 alertText2:testText2 playTone:testPlayTone duration:testDuration];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(beNil());
- expect(testAlert.ttsChunks.firstObject.text).to(equal(testTTSString));
- expect(testAlert.duration).to(equal(testDuration));
- expect(testAlert.playTone).to(beTrue());
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
+ expect(testRequest.alertText1).to(beNil());
+ expect(testRequest.alertText2).to(beNil());
+ expect(testRequest.alertText3).to(beNil());
+ expect(testRequest.ttsChunks).to(beNil());
+ expect(testRequest.duration).to(beNil());
+ expect(testRequest.playTone).to(beNil());
+ expect(testRequest.progressIndicator).to(beNil());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+
+ expect(testRequest.parameters.count).to(equal(0));
});
+ });
+
+ describe(@"Initializing", ^{
+ it(@"Should initialize correctly with a dictionary", ^{
+ NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameAlertText1:testAlertText1,
+ SDLRPCParameterNameAlertText2:testAlertText2,
+ SDLRPCParameterNameAlertText3:testAlertText3,
+ SDLRPCParameterNameTTSChunks:testTTSChunks,
+ SDLRPCParameterNameDuration:@(testDuration),
+ SDLRPCParameterNamePlayTone:@(testPlayTone),
+ SDLRPCParameterNameProgressIndicator:@(testProgressIndicator),
+ SDLRPCParameterNameSoftButtons:testSoftButtons,
+ SDLRPCParameterNameAlertIcon:testImage,
+ SDLRPCParameterNameCancelID:@(testCancelID)},
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameAlert}};
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithDictionary:dict];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(equal(testTTSChunks));
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(equal(testProgressIndicator));
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.alertIcon).to(equal(testImage));
+ expect(testRequest.cancelID).to(equal(testCancelID));
- it(@"should initialize correctly with initWithTTS:alertText1:alertText2:alertText3:playTone:duration:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithTTS:testTTSString alertText1:testText1 alertText2:testText2 alertText3:testText3 playTone:testPlayTone duration:testDuration];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(equal(testText3));
- expect(testAlert.ttsChunks.firstObject.text).to(equal(testTTSString));
- expect(testAlert.duration).to(equal(testDuration));
- expect(testAlert.playTone).to(equal(testPlayTone));
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
+ expect(testRequest.parameters.count).to(equal(10));
});
- it(@"should initialize correctly with initWithTTS:playTone:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithTTS:testTTSString playTone:testPlayTone];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(beNil());
- expect(testAlert.alertText2).to(beNil());
- expect(testAlert.alertText3).to(beNil());
- expect(testAlert.ttsChunks.firstObject.text).to(equal(testTTSString));
- expect(testAlert.duration).to(equal(defaultDuration));
- expect(testAlert.playTone).to(equal(testPlayTone));
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
+ it(@"Should initialize correctly with initWithAlertText:softButtons:playTone:ttsChunks:cancelID:", ^{
+ testRequest = [[SDLAlert alloc] initWithAlertText:testAlertText1 softButtons:testSoftButtons playTone:testPlayTone ttsChunks:testTTSChunks alertIcon:testImage cancelID:testCancelID];
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(beNil());
+ expect(testRequest.alertText3).to(beNil());
+ expect(testRequest.ttsChunks).to(equal(testTTSChunks));
+ expect(testRequest.duration).to(beNil());
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.alertIcon).to(equal(testImage));
+ expect(testRequest.cancelID).to(equal(testCancelID));
});
- it(@"should initialize correctly with initWithTTSChunks:alertText1:alertText2:alertText3:playTone:softButtons:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithTTSChunks:@[tts] alertText1:testText1 alertText2:testText2 alertText3:testText3 playTone:testPlayTone softButtons:@[button]];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(equal(testText3));
- expect(testAlert.ttsChunks).to(haveCount(1));
- expect(testAlert.duration).to(equal(defaultDuration));
- expect(testAlert.playTone).to(equal(testPlayTone));
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(haveCount(1));
- expect(testAlert.alertIcon).to(beNil());
+ it(@"Should initialize correctly with initWithAlertText:softButtons:playTone:ttsChunks:cancelID:", ^{
+ testRequest = [[SDLAlert alloc] initWithAlertText1:testAlertText1 alertText2:testAlertText2 alertText3:testAlertText3 softButtons:testSoftButtons playTone:testPlayTone ttsChunks:testTTSChunks duration:testDuration progressIndicator:testProgressIndicator alertIcon:testImage cancelID:testCancelID];
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(equal(testTTSChunks));
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(equal(testProgressIndicator));
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.alertIcon).to(equal(testImage));
+ expect(testRequest.cancelID).to(equal(testCancelID));
});
- it(@"should initialize correctly with initWithTTSChunks:alertText1:alertText2:alertText3:playTone:duration:softButtons:", ^{
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert *testAlert = [[SDLAlert alloc] initWithTTSChunks:@[tts] alertText1:testText1 alertText2:testText2 alertText3:testText3 playTone:testPlayTone duration:testDuration softButtons:@[button]];
-#pragma clang diagnostic pop
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(equal(testText3));
- expect(testAlert.ttsChunks).to(haveCount(1));
- expect(testAlert.duration).to(equal(testDuration));
- expect(testAlert.playTone).to(equal(testPlayTone));
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(haveCount(1));
- expect(testAlert.alertIcon).to(beNil());
+ it(@"Should initialize correctly with initWithAlertText1:alertText2:duration:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithAlertText1:testAlertText1 alertText2:testAlertText2 duration:testDuration];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(beNil());
+ expect(testRequest.ttsChunks).to(beNil());
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(beFalse());
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
- it(@"should initialize correctly with initWithAlertText1:alertText2:", ^{
- SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2];
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(beNil());
- expect(testAlert.ttsChunks).to(beNil());
- expect(testAlert.duration).to(equal(defaultDuration));
- expect(testAlert.playTone).to(beFalse());
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
+ it(@"Should initialize correctly with initWithAlertText1:alertText2:alertText3:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithAlertText1:testAlertText1 alertText2:testAlertText2 alertText3:testAlertText3];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(beNil());
+ expect(testRequest.duration).to(equal(SDLDefaultDuration));
+ expect(testRequest.playTone).to(beFalse());
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
- it(@"should initialize correctly with initWithTTSChunks:playTone:", ^{
- SDLAlert *testAlert = [[SDLAlert alloc] initWithTTSChunks:@[tts] playTone:testPlayTone];
-
- expect(testAlert.alertText1).to(beNil());
- expect(testAlert.alertText2).to(beNil());
- expect(testAlert.alertText3).to(beNil());
- expect(testAlert.ttsChunks).to(haveCount(1));
- expect(testAlert.duration).to(equal(defaultDuration));
- expect(testAlert.playTone).to(equal(testPlayTone));
- expect(testAlert.progressIndicator).to(beFalse());
- expect(testAlert.softButtons).to(beNil());
- expect(testAlert.alertIcon).to(beNil());
+ it(@"Should initialize correctly with initWithAlertText1:alertText2:alertText3:duration", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithAlertText1:testAlertText1 alertText2:testAlertText2 alertText3:testAlertText3 duration:testDuration];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(beNil());
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(beFalse());
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
- it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:ttsChunks:playTone:progressIndicator:duration:softButtons:alertIcon:", ^{
- SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3 ttsChunks:@[tts] playTone:testPlayTone progressIndicator:testProgressIndicator duration:testDuration softButtons:@[button] alertIcon:testImage];
-
- expect(testAlert.alertText1).to(equal(testText1));
- expect(testAlert.alertText2).to(equal(testText2));
- expect(testAlert.alertText3).to(equal(testText3));
- expect(testAlert.ttsChunks).to(haveCount(1));
- expect(testAlert.duration).to(equal(testDuration));
- expect(testAlert.playTone).to(equal(testPlayTone));
- expect(testAlert.progressIndicator).to(beTrue());
- expect(testAlert.softButtons).to(haveCount(1));
- expect(testAlert.alertIcon.value).to(equal(testImage.value));
+ it(@"Should initialize correctly with initWithAlertText1:alertText2:alertText3:duration:softButtons:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithAlertText1:testAlertText1 alertText2:testAlertText2 alertText3:testAlertText3 duration:testDuration softButtons:testSoftButtons];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(beNil());
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(beFalse());
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
- });
- describe(@"Getter/Setter Tests", ^ {
- it(@"Should set and get correctly", ^ {
- SDLAlert* testRequest = [[SDLAlert alloc] init];
-
- testRequest.alertText1 = @"alert#1";
- testRequest.alertText2 = @"alert#2";
- testRequest.alertText3 = @"alert#3";
- testRequest.ttsChunks = @[tts];
- testRequest.duration = @4357;
- testRequest.playTone = @YES;
- testRequest.progressIndicator = @NO;
- testRequest.softButtons = @[button];
- testRequest.alertIcon = testImage;
+ it(@"Should initialize correctly with initWithTTS:playTone:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithTTS:testTTSString playTone:testPlayTone];
+ #pragma clang diagnostic pop
- expect(testRequest.alertText1).to(equal(@"alert#1"));
- expect(testRequest.alertText2).to(equal(@"alert#2"));
- expect(testRequest.alertText3).to(equal(@"alert#3"));
- expect(testRequest.ttsChunks).to(equal(@[tts]));
- expect(testRequest.duration).to(equal(@4357));
- expect(testRequest.playTone).to(equal(@YES));
- expect(testRequest.progressIndicator).to(equal(@NO));
- expect(testRequest.softButtons).to(equal(@[button]));
- expect(testRequest.alertIcon).to(equal(testImage));
+ expect(testRequest.alertText1).to(beNil());
+ expect(testRequest.alertText2).to(beNil());
+ expect(testRequest.alertText3).to(beNil());
+ expect(testRequest.ttsChunks).to(equal([SDLTTSChunk textChunksFromString:testTTSString]));
+ expect(testRequest.duration).to(equal(SDLDefaultDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
- it(@"Should get correctly when initialized", ^ {
- NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameAlertText1: @"alert#1",
- SDLRPCParameterNameAlertText2: @"alert#2",
- SDLRPCParameterNameAlertText3: @"alert#3",
- SDLRPCParameterNameTTSChunks: @[tts],
- SDLRPCParameterNameDuration: @4357,
- SDLRPCParameterNamePlayTone: @YES,
- SDLRPCParameterNameProgressIndicator: @NO,
- SDLRPCParameterNameSoftButtons: @[button],
- SDLRPCParameterNameAlertIcon: testImage
- },
- SDLRPCParameterNameOperationName: SDLRPCFunctionNameAlert
- }
- };
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert* testRequest = [[SDLAlert alloc] initWithDictionary:dict];
-#pragma clang diagnostic pop
-
- expect(testRequest.alertText1).to(equal(@"alert#1"));
- expect(testRequest.alertText2).to(equal(@"alert#2"));
- expect(testRequest.alertText3).to(equal(@"alert#3"));
- expect(testRequest.ttsChunks).to(equal([@[tts] mutableCopy]));
- expect(testRequest.duration).to(equal(@4357));
- expect(testRequest.playTone).to(equal(@YES));
- expect(testRequest.progressIndicator).to(equal(@NO));
- expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
+ it(@"Should initialize correctly with initWithTTS:alertText1:alertText2:playTone:duration:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithTTS:testTTSString alertText1:testAlertText1 alertText2:testAlertText2 playTone:testPlayTone duration:testDuration];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(beNil());
+ expect(testRequest.ttsChunks).to(equal([SDLTTSChunk textChunksFromString:testTTSString]));
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
- it(@"Should handle NSNull", ^{
- NSDictionary* dict = @{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameAlertText1: @"alert#1",
- SDLRPCParameterNameAlertText2: @"alert#2",
- SDLRPCParameterNameAlertText3: @"alert#3",
- SDLRPCParameterNameTTSChunks: @[tts],
- SDLRPCParameterNameDuration: @4357,
- SDLRPCParameterNamePlayTone: @YES,
- SDLRPCParameterNameProgressIndicator: @NO,
- SDLRPCParameterNameSoftButtons: [NSNull null],
- SDLRPCParameterNameAlertIcon: testImage
- },
- SDLRPCParameterNameOperationName:SDLRPCFunctionNameAlert}
- };
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert* testRequest = [[SDLAlert alloc] initWithDictionary:dict];
-#pragma clang diagnostic pop
- expectAction(^{
- NSArray<SDLSoftButton *> *softButtons = testRequest.softButtons;
- }).to(raiseException());
+ it(@"Should initialize correctly with initWithTTS:alertText1:alertText2:alertText3:playTone:duration:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithTTS:testTTSString alertText1:testAlertText1 alertText2:testAlertText2 alertText3:testAlertText3 playTone:testPlayTone duration:testDuration];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(equal([SDLTTSChunk textChunksFromString:testTTSString]));
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
- it(@"Should return nil if not set", ^ {
- SDLAlert* testRequest = [[SDLAlert alloc] init];
+ it(@"Should initialize correctly with initWithTTSChunks:playTone:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithTTSChunks:testTTSChunks playTone:testPlayTone];
+ #pragma clang diagnostic pop
expect(testRequest.alertText1).to(beNil());
expect(testRequest.alertText2).to(beNil());
expect(testRequest.alertText3).to(beNil());
- expect(testRequest.ttsChunks).to(beNil());
+ expect(testRequest.ttsChunks).to(equal(testTTSChunks));
expect(testRequest.duration).to(beNil());
- expect(testRequest.playTone).to(beNil());
- expect(testRequest.progressIndicator).to(beNil());
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(beFalse());
expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithTTSChunks:alertText1:alertText2:alertText3:playTone:softButtons:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithTTSChunks:testTTSChunks alertText1:testAlertText1 alertText2:testAlertText2 alertText3:testAlertText3 playTone:testPlayTone softButtons:testSoftButtons];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(equal(testTTSChunks));
+ expect(testRequest.duration).to(equal(SDLDefaultDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
});
+
+ it(@"Should initialize correctly with initWithTTSChunks:alertText1:alertText2:alertText3:playTone:duration:softButtons:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLAlert alloc] initWithTTSChunks:testTTSChunks alertText1:testAlertText1 alertText2:testAlertText2 alertText3:testAlertText3 playTone:testPlayTone duration:testDuration softButtons:testSoftButtons];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(testAlertText1));
+ expect(testRequest.alertText2).to(equal(testAlertText2));
+ expect(testRequest.alertText3).to(equal(testAlertText3));
+ expect(testRequest.ttsChunks).to(equal(testTTSChunks));
+ expect(testRequest.duration).to(equal(testDuration));
+ expect(testRequest.playTone).to(equal(testPlayTone));
+ expect(testRequest.progressIndicator).to(beFalse());
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.alertIcon).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+ });
+
+ afterEach(^{
+ expect(testRequest.name).to(equal(SDLRPCFunctionNameAlert));
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m
new file mode 100644
index 000000000..63bcce755
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m
@@ -0,0 +1,142 @@
+//
+// SDLCancelInteractionSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Nicole on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLCancelInteraction.h"
+#import "SDLFunctionID.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLRPCParameterNames.h"
+
+QuickSpecBegin(SDLCancelInteractionSpec)
+
+describe(@"Getter/Setter Tests", ^{
+ __block SDLCancelInteraction *testRequest = nil;
+ __block UInt32 testFunctionID = 45;
+ __block UInt32 testCancelID = 23;
+
+ it(@"Should set and get correctly", ^{
+ testRequest = [[SDLCancelInteraction alloc] init];
+ testRequest.cancelID = @(testCancelID);
+ testRequest.functionID = @(testFunctionID);
+
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ expect(testRequest.functionID).to(equal(testFunctionID));
+
+ expect(testRequest.name).to(match(SDLRPCFunctionNameCancelInteraction));
+ expect(testRequest.parameters.count).to(equal(2));
+ });
+
+ it(@"Should return nil if not set", ^{
+ testRequest = [[SDLCancelInteraction alloc] init];
+
+ expect(testRequest.cancelID).to(beNil());
+ expect(testRequest.functionID).to(beNil());
+
+ expect(testRequest.parameters.count).to(equal(0));
+ });
+
+ describe(@"initializing", ^{
+ it(@"Should initialize correctly with a dictionary", ^{
+ NSDictionary *dict = @{SDLRPCParameterNameRequest:@{
+ SDLRPCParameterNameParameters:@{
+ SDLRPCParameterNameCancelID:@(testCancelID),
+ SDLRPCParameterNameFunctionID:@(testFunctionID)
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameCancelInteraction}};
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLCancelInteraction alloc] initWithDictionary:dict];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ expect(testRequest.functionID).to(equal(testFunctionID));
+
+ expect(testRequest.parameters.count).to(equal(2));
+ });
+
+ it(@"Should initialize correctly with initWithfunctionID:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithFunctionID:testFunctionID];
+
+ expect(testRequest.functionID).to(equal(testFunctionID));
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithfunctionID:cancelID:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithFunctionID:testFunctionID cancelID:testCancelID];
+
+ expect(testRequest.functionID).to(equal(testFunctionID));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithAlertCancelID:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithAlertCancelID:testCancelID];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameAlert]));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithSliderCancelID:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithSliderCancelID:testCancelID];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSlider]));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithScrollableMessageCancelID:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithScrollableMessageCancelID:testCancelID];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameScrollableMessage]));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithPerformInteractionCancelID:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithPerformInteractionCancelID:testCancelID];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction]));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithAlert:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithAlert];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameAlert]));
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithSlider:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithSlider];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSlider]));
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithScrollableMessage:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithScrollableMessage];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameScrollableMessage]));
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithPerformInteraction:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithPerformInteraction];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction]));
+ expect(testRequest.cancelID).to(beNil());
+ });
+ });
+
+ afterEach(^{
+ expect(testRequest.name).to(match(SDLRPCFunctionNameCancelInteraction));
+ });
+});
+
+QuickSpecEnd
+
+
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLPerformInteractionSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLPerformInteractionSpec.m
index 6424d27f7..aa28359d3 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLPerformInteractionSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLPerformInteractionSpec.m
@@ -18,77 +18,292 @@
QuickSpecBegin(SDLPerformInteractionSpec)
-SDLTTSChunk* chunk1 = [[SDLTTSChunk alloc] init];
-SDLTTSChunk* chunk2 = [[SDLTTSChunk alloc] init];
-SDLTTSChunk* chunk3 = [[SDLTTSChunk alloc] init];
-SDLVRHelpItem* helpItem = [[SDLVRHelpItem alloc] init];
-
describe(@"Getter/Setter Tests", ^ {
- it(@"Should set and get correctly", ^ {
- SDLPerformInteraction* testRequest = [[SDLPerformInteraction alloc] init];
-
- testRequest.initialText = @"a";
- testRequest.initialPrompt = [@[chunk1] mutableCopy];
- testRequest.interactionMode = SDLInteractionModeVoiceRecognitionOnly;
- testRequest.interactionChoiceSetIDList = [@[@1, @2, @3] mutableCopy];
- testRequest.helpPrompt = [@[chunk2] mutableCopy];
- testRequest.timeoutPrompt = [@[chunk3] mutableCopy];
- testRequest.timeout = @42000;
- testRequest.vrHelp = [@[helpItem] mutableCopy];
- testRequest.interactionLayout = SDLLayoutModeIconWithSearch;
-
- expect(testRequest.initialText).to(equal(@"a"));
- expect(testRequest.initialPrompt).to(equal([@[chunk1] mutableCopy]));
- expect(testRequest.interactionMode).to(equal(SDLInteractionModeVoiceRecognitionOnly));
- expect(testRequest.interactionChoiceSetIDList).to(equal([@[@1, @2, @3] mutableCopy]));
- expect(testRequest.helpPrompt).to(equal([@[chunk2] mutableCopy]));
- expect(testRequest.timeoutPrompt).to(equal([@[chunk3] mutableCopy]));
- expect(testRequest.timeout).to(equal(@42000));
- expect(testRequest.vrHelp).to(equal([@[helpItem] mutableCopy]));
- expect(testRequest.interactionLayout).to(equal(SDLLayoutModeIconWithSearch));
+ __block SDLPerformInteraction *testRequest = nil;
+ __block NSString *testInitialText = @"initialText";
+ __block NSArray<SDLTTSChunk *> *testInitialPrompt = nil;
+ __block NSString *testInitialPromptString = nil;
+ __block SDLInteractionMode testInteractionMode = SDLInteractionModeVoiceRecognitionOnly;
+ __block NSArray<NSNumber<SDLUInt> *> *testInteractionChoiceSetIDList = nil;
+ __block UInt16 testInteractionChoiceSetID = 48212;
+ __block NSString *testHelpPromptString = nil;
+ __block NSArray<SDLTTSChunk *> *testHelpPrompt = nil;
+ __block NSString *testTimeoutPromptString = nil;
+ __block NSArray<SDLTTSChunk *> *testTimeoutPrompt = nil;
+ __block int testTimeout = 6000;
+ __block NSArray<SDLVRHelpItem *> *testVRHelp = nil;
+ __block SDLLayoutMode testinteractionLayout = SDLLayoutModeKeyboard;
+ __block int testCancelID = 9987;
+
+ beforeEach(^{
+ testInteractionChoiceSetIDList = @[@34, @55, @23];
+ testInitialPromptString = @"test initial prompt";
+ testInitialPrompt = [SDLTTSChunk textChunksFromString:testInitialPromptString];
+ testHelpPromptString = @"test help prompt";
+ testHelpPrompt = [SDLTTSChunk textChunksFromString:testHelpPromptString];
+ testTimeoutPromptString = @"test timeout prompt";
+ testTimeoutPrompt = [SDLTTSChunk textChunksFromString:testTimeoutPromptString];
+ testVRHelp = @[[[SDLVRHelpItem alloc] initWithText:@"test vr help" image:nil]];
});
-
- it(@"Should get correctly when initialized", ^ {
- NSMutableDictionary* dict = [@{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameInitialText:@"a",
- SDLRPCParameterNameInitialPrompt:[@[chunk1] mutableCopy],
- SDLRPCParameterNameInteractionMode:SDLInteractionModeVoiceRecognitionOnly,
- SDLRPCParameterNameInteractionChoiceSetIdList:[@[@1, @2, @3] mutableCopy],
- SDLRPCParameterNameHelpPrompt:[@[chunk2] mutableCopy],
- SDLRPCParameterNameTimeoutPrompt:[@[chunk3] mutableCopy],
- SDLRPCParameterNameTimeout:@42000,
- SDLRPCParameterNameVRHelp:[@[helpItem] mutableCopy],
- SDLRPCParameterNameInteractionLayout:SDLLayoutModeIconWithSearch},
- SDLRPCParameterNameOperationName:SDLRPCFunctionNamePerformInteraction}} mutableCopy];
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLPerformInteraction* testRequest = [[SDLPerformInteraction alloc] initWithDictionary:dict];
-#pragma clang diagnostic pop
-
- expect(testRequest.initialText).to(equal(@"a"));
- expect(testRequest.initialPrompt).to(equal([@[chunk1] mutableCopy]));
- expect(testRequest.interactionMode).to(equal(SDLInteractionModeVoiceRecognitionOnly));
- expect(testRequest.interactionChoiceSetIDList).to(equal([@[@1, @2, @3] mutableCopy]));
- expect(testRequest.helpPrompt).to(equal([@[chunk2] mutableCopy]));
- expect(testRequest.timeoutPrompt).to(equal([@[chunk3] mutableCopy]));
- expect(testRequest.timeout).to(equal(@42000));
- expect(testRequest.vrHelp).to(equal([@[helpItem] mutableCopy]));
- expect(testRequest.interactionLayout).to(equal(SDLLayoutModeIconWithSearch));
+
+ context(@"Getter/Setter Tests", ^{
+ it(@"Should set and get correctly", ^ {
+ testRequest = [[SDLPerformInteraction alloc] init];
+
+ testRequest.initialText = testInitialText;
+ testRequest.initialPrompt = testInitialPrompt;
+ testRequest.interactionMode = testInteractionMode;
+ testRequest.interactionChoiceSetIDList = testInteractionChoiceSetIDList;
+ testRequest.helpPrompt = testHelpPrompt;
+ testRequest.timeoutPrompt = testTimeoutPrompt;
+ testRequest.timeout = @(testTimeout);
+ testRequest.vrHelp = testVRHelp;
+ testRequest.interactionLayout = testinteractionLayout;
+ testRequest.cancelID = @(testCancelID);
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal(testInitialPrompt));
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(equal(testHelpPrompt));
+ expect(testRequest.timeoutPrompt).to(equal(testTimeoutPrompt));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.vrHelp).to(equal(testVRHelp));
+ expect(testRequest.interactionLayout).to(equal(testinteractionLayout));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+
+ expect(testRequest.parameters.count).to(equal(10));
+ });
+
+ it(@"Should return nil if not set", ^ {
+ testRequest = [[SDLPerformInteraction alloc] init];
+
+ expect(testRequest.initialText).to(beNil());
+ expect(testRequest.initialPrompt).to(beNil());
+ expect(testRequest.interactionMode).to(beNil());
+ expect(testRequest.interactionChoiceSetIDList).to(beNil());
+ expect(testRequest.helpPrompt).to(beNil());
+ expect(testRequest.timeoutPrompt).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.vrHelp).to(beNil());
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+
+ expect(testRequest.parameters.count).to(equal(0));
+ });
+ });
+
+ describe(@"Initializing", ^{
+ it(@"Should initialize correctly with a dictionary", ^ {
+ NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameInitialText:testInitialText,
+ SDLRPCParameterNameInitialPrompt:testInitialPrompt,
+ SDLRPCParameterNameInteractionMode:testInteractionMode,
+ SDLRPCParameterNameInteractionChoiceSetIdList:testInteractionChoiceSetIDList,
+ SDLRPCParameterNameHelpPrompt:testHelpPrompt,
+ SDLRPCParameterNameTimeoutPrompt:testTimeoutPrompt,
+ SDLRPCParameterNameTimeout:@(testTimeout),
+ SDLRPCParameterNameVRHelp:testVRHelp,
+ SDLRPCParameterNameInteractionLayout:testinteractionLayout,
+ SDLRPCParameterNameCancelID:@(testCancelID)},
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNamePerformInteraction}};
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithDictionary:dict];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal(testInitialPrompt));
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(equal(testHelpPrompt));
+ expect(testRequest.timeoutPrompt).to(equal(testTimeoutPrompt));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.vrHelp).to(equal(testVRHelp));
+ expect(testRequest.interactionLayout).to(equal(testinteractionLayout));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+
+ expect(testRequest.parameters.count).to(equal(10));
+ });
+
+ it(@"Should initialize correctly with initWithInitialText:interactionMode:interactionChoiceSetIDList:cancelID:", ^{
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialText:testInitialText interactionMode:testInteractionMode interactionChoiceSetIDList:testInteractionChoiceSetIDList cancelID:testCancelID];
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(beNil());
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(beNil());
+ expect(testRequest.timeoutPrompt).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.vrHelp).to(beNil());
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithInitialText:initialPrompt:interactionMode:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:timeout:vrHelp:interactionLayout:cancelID:", ^{
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialText:testInitialText initialPrompt:testInitialPrompt interactionMode:testInteractionMode interactionChoiceSetIDList:testInteractionChoiceSetIDList helpPrompt:testHelpPrompt timeoutPrompt:testTimeoutPrompt timeout:testTimeout vrHelp:testVRHelp interactionLayout:testinteractionLayout cancelID:testCancelID];
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal(testInitialPrompt));
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(equal(testHelpPrompt));
+ expect(testRequest.timeoutPrompt).to(equal(testTimeoutPrompt));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.vrHelp).to(equal(testVRHelp));
+ expect(testRequest.interactionLayout).to(equal(testinteractionLayout));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithInteractionChoiceSetId:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInteractionChoiceSetId:testInteractionChoiceSetID];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(beNil());
+ expect(testRequest.initialPrompt).to(beNil());
+ expect(testRequest.interactionMode).to(beNil());
+ expect(testRequest.interactionChoiceSetIDList).to(equal(@[@(testInteractionChoiceSetID)]));
+ expect(testRequest.helpPrompt).to(beNil());
+ expect(testRequest.timeoutPrompt).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.vrHelp).to(beNil());
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithInteractionChoiceSetIdList:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInteractionChoiceSetIdList:testInteractionChoiceSetIDList];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(beNil());
+ expect(testRequest.initialPrompt).to(beNil());
+ expect(testRequest.interactionMode).to(beNil());
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(beNil());
+ expect(testRequest.timeoutPrompt).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.vrHelp).to(beNil());
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithInitialPrompt:initialText:interactionChoiceSetID:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialPrompt:testInitialPromptString initialText:testInitialText interactionChoiceSetID:testInteractionChoiceSetID];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal([SDLTTSChunk textChunksFromString:testInitialPromptString]));
+ expect(testRequest.interactionMode).to(beNil());
+ expect(testRequest.interactionChoiceSetIDList).to(equal(@[@(testInteractionChoiceSetID)]));
+ expect(testRequest.helpPrompt).to(beNil());
+ expect(testRequest.timeoutPrompt).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.vrHelp).to(beNil());
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithInitialPrompt:initialText:interactionChoiceSetID:vrHelp:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialPrompt:testInitialPromptString initialText:testInitialText interactionChoiceSetID:testInteractionChoiceSetID vrHelp:testVRHelp];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal([SDLTTSChunk textChunksFromString:testInitialPromptString]));
+ expect(testRequest.interactionMode).to(beNil());
+ expect(testRequest.interactionChoiceSetIDList).to(equal(@[@(testInteractionChoiceSetID)]));
+ expect(testRequest.helpPrompt).to(beNil());
+ expect(testRequest.timeoutPrompt).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.vrHelp).to(equal(testVRHelp));
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithInitialPrompt:initialText:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:interactionMode:timeout:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialPrompt:testInitialPromptString initialText:testInitialText interactionChoiceSetIDList:testInteractionChoiceSetIDList helpPrompt:testHelpPromptString timeoutPrompt:testTimeoutPromptString interactionMode:testInteractionMode timeout:testTimeout];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal([SDLTTSChunk textChunksFromString:testInitialPromptString]));
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(equal([SDLTTSChunk textChunksFromString:testHelpPromptString]));
+ expect(testRequest.timeoutPrompt).to(equal([SDLTTSChunk textChunksFromString:testTimeoutPromptString]));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.vrHelp).to(beNil());
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithInitialPrompt:initialText:interactionChoiceSetIDList:helpPrompt:timeoutPrompt:interactionMode:timeout:vrHelp:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialPrompt:testInitialPromptString initialText:testInitialText interactionChoiceSetIDList:testInteractionChoiceSetIDList helpPrompt:testHelpPromptString timeoutPrompt:testTimeoutPromptString interactionMode:testInteractionMode timeout:testTimeout vrHelp:testVRHelp];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal([SDLTTSChunk textChunksFromString:testInitialPromptString]));
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(equal([SDLTTSChunk textChunksFromString:testHelpPromptString]));
+ expect(testRequest.timeoutPrompt).to(equal([SDLTTSChunk textChunksFromString:testTimeoutPromptString]));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.vrHelp).to(equal(testVRHelp));
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithInitialChunks:initialText:interactionChoiceSetIDList:helpChunks:timeoutChunks:interactionMode:timeout:vrHelp:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialChunks:testInitialPrompt initialText:testInitialText interactionChoiceSetIDList:testInteractionChoiceSetIDList helpChunks:testHelpPrompt timeoutChunks:testTimeoutPrompt interactionMode:testInteractionMode timeout:testTimeout vrHelp:testVRHelp];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal(testInitialPrompt));
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(equal(testHelpPrompt));
+ expect(testRequest.timeoutPrompt).to(equal(testTimeoutPrompt));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.vrHelp).to(equal(testVRHelp));
+ expect(testRequest.interactionLayout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"Should initialize correctly with initWithInitialChunks:initialText:interactionChoiceSetIDList:helpChunks:timeoutChunks:interactionMode:timeout:vrHelp:interactionLayout:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLPerformInteraction alloc] initWithInitialChunks:testInitialPrompt initialText:testInitialText interactionChoiceSetIDList:testInteractionChoiceSetIDList helpChunks:testHelpPrompt timeoutChunks:testTimeoutPrompt interactionMode:testInteractionMode timeout:testTimeout vrHelp:testVRHelp interactionLayout:testinteractionLayout];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.initialText).to(equal(testInitialText));
+ expect(testRequest.initialPrompt).to(equal(testInitialPrompt));
+ expect(testRequest.interactionMode).to(equal(testInteractionMode));
+ expect(testRequest.interactionChoiceSetIDList).to(equal(testInteractionChoiceSetIDList));
+ expect(testRequest.helpPrompt).to(equal(testHelpPrompt));
+ expect(testRequest.timeoutPrompt).to(equal(testTimeoutPrompt));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.vrHelp).to(equal(testVRHelp));
+ expect(testRequest.interactionLayout).to(equal(testinteractionLayout));
+ expect(testRequest.cancelID).to(beNil());
+ });
});
-
- it(@"Should return nil if not set", ^ {
- SDLPerformInteraction* testRequest = [[SDLPerformInteraction alloc] init];
-
- expect(testRequest.initialText).to(beNil());
- expect(testRequest.initialPrompt).to(beNil());
- expect(testRequest.interactionMode).to(beNil());
- expect(testRequest.interactionChoiceSetIDList).to(beNil());
- expect(testRequest.helpPrompt).to(beNil());
- expect(testRequest.timeoutPrompt).to(beNil());
- expect(testRequest.timeout).to(beNil());
- expect(testRequest.vrHelp).to(beNil());
- expect(testRequest.interactionLayout).to(beNil());
+
+ afterEach(^{
+ expect(testRequest.name).to(equal(SDLRPCFunctionNamePerformInteraction));
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLScrollableMessageSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLScrollableMessageSpec.m
index 0514b1936..58a86d751 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLScrollableMessageSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLScrollableMessageSpec.m
@@ -2,9 +2,6 @@
// SDLScrollableMessageSpec.m
// SmartDeviceLink
-
-#import <Foundation/Foundation.h>
-
#import <Quick/Quick.h>
#import <Nimble/Nimble.h>
@@ -15,44 +12,101 @@
QuickSpecBegin(SDLScrollableMessageSpec)
-SDLSoftButton* button = [[SDLSoftButton alloc] init];
-
describe(@"Getter/Setter Tests", ^ {
- it(@"Should set and get correctly", ^ {
- SDLScrollableMessage* testRequest = [[SDLScrollableMessage alloc] init];
-
- testRequest.scrollableMessageBody = @"thatmessagebody";
- testRequest.timeout = @9182;
- testRequest.softButtons = [@[button] mutableCopy];
-
- expect(testRequest.scrollableMessageBody).to(equal(@"thatmessagebody"));
- expect(testRequest.timeout).to(equal(@9182));
- expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
+ __block SDLScrollableMessage *testRequest = nil;
+ __block NSString *testScrollableMessageBody = nil;
+ __block int testTimeout = 6542;
+ __block NSArray<SDLSoftButton *> *testSoftButtons = nil;
+ __block int testCancelID = 69;
+
+ beforeEach(^{
+ testScrollableMessageBody = @"Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.\nNow we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war.";
+ testSoftButtons = @[[[SDLSoftButton alloc] init]];
+ });
+
+ context(@"Getter/Setter Tests", ^{
+ it(@"Should set and get correctly", ^ {
+ testRequest = [[SDLScrollableMessage alloc] init];
+
+ testRequest.scrollableMessageBody = testScrollableMessageBody;
+ testRequest.timeout = @(testTimeout);
+ testRequest.softButtons = testSoftButtons;
+ testRequest.cancelID = @(testCancelID);
+
+ expect(testRequest.scrollableMessageBody).to(equal(testScrollableMessageBody));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+
+ expect(testRequest.parameters.count).to(equal(4));
+ });
+
+ it(@"Should return nil if not set", ^{
+ testRequest = [[SDLScrollableMessage alloc] init];
+
+ expect(testRequest.scrollableMessageBody).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+
+ expect(testRequest.parameters.count).to(equal(0));
+ });
});
-
- it(@"Should get correctly when initialized", ^ {
- NSMutableDictionary<NSString *, id> *dict = [@{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameScrollableMessageBody:@"thatmessagebody",
- SDLRPCParameterNameTimeout:@9182,
- SDLRPCParameterNameSoftButtons:[@[button] mutableCopy]},
- SDLRPCParameterNameOperationName:SDLRPCFunctionNameScrollableMessage}} mutableCopy];
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLScrollableMessage* testRequest = [[SDLScrollableMessage alloc] initWithDictionary:dict];
-#pragma clang diagnostic pop
-
- expect(testRequest.scrollableMessageBody).to(equal(@"thatmessagebody"));
- expect(testRequest.timeout).to(equal(@9182));
- expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
+
+ describe(@"Initializing", ^{
+ it(@"Should initialize correctly with a dictionary", ^ {
+ NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameScrollableMessageBody:testScrollableMessageBody,
+ SDLRPCParameterNameTimeout:@(testTimeout),
+ SDLRPCParameterNameSoftButtons:testSoftButtons,
+ SDLRPCParameterNameCancelID:@(testCancelID)},
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameScrollableMessage}};
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLScrollableMessage alloc] initWithDictionary:dict];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.scrollableMessageBody).to(equal(testScrollableMessageBody));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithMessage:", ^{
+ testRequest = [[SDLScrollableMessage alloc] initWithMessage:testScrollableMessageBody];
+
+ expect(testRequest.scrollableMessageBody).to(equal(testScrollableMessageBody));
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.softButtons).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+
+ it(@"Should initialize correctly with initWithMessage:timeout:softButtons:cancelID:", ^{
+ testRequest = [[SDLScrollableMessage alloc] initWithMessage:testScrollableMessageBody timeout:testTimeout softButtons:testSoftButtons cancelID:testCancelID];
+
+ expect(testRequest.scrollableMessageBody).to(equal(testScrollableMessageBody));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithMessage:timeout:softButtons:", ^{
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLScrollableMessage alloc] initWithMessage:testScrollableMessageBody timeout:testTimeout softButtons:testSoftButtons];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.scrollableMessageBody).to(equal(testScrollableMessageBody));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.softButtons).to(equal(testSoftButtons));
+ expect(testRequest.cancelID).to(beNil());
+ });
});
-
- it(@"Should return nil if not set", ^ {
- SDLScrollableMessage* testRequest = [[SDLScrollableMessage alloc] init];
-
- expect(testRequest.scrollableMessageBody).to(beNil());
- expect(testRequest.timeout).to(beNil());
- expect(testRequest.softButtons).to(beNil());
+
+ afterEach(^{
+ expect(testRequest.name).to(equal(SDLRPCFunctionNameScrollableMessage));
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSliderSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSliderSpec.m
index 7689b8904..b8478240d 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSliderSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSliderSpec.m
@@ -22,89 +22,115 @@ describe(@"Getter/Setter Tests", ^ {
__block NSString *testHeader = @"Head";
__block NSString *testFooter = @"Foot";
__block NSArray<NSString *> *testFooters = @[@"Foot1", @"Foot2"];
+ __block int testCancelID = 56;
- beforeEach(^{
- testRequest = nil;
- testNumTicks = 4;
- testPosition = 1;
- testTimeout = 2000;
- testHeader = @"Head";
- testFooter = @"Foot";
- testFooters = @[@"Foot1", @"Foot2"];
- });
+ context(@"Getter/Setter Tests", ^{
+ it(@"Should set and get correctly", ^ {
+ testRequest = [[SDLSlider alloc] init];
- it(@"Should set and get correctly", ^ {
- testRequest = [[SDLSlider alloc] init];
-
- testRequest.numTicks = @(testNumTicks);
- testRequest.position = @(testPosition);
- testRequest.sliderHeader = testHeader;
- testRequest.sliderFooter = testFooters;
- testRequest.timeout = @(testTimeout);
-
- expect(testRequest.numTicks).to(equal(testNumTicks));
- expect(testRequest.position).to(equal(testPosition));
- expect(testRequest.sliderHeader).to(equal(testHeader));
- expect(testRequest.sliderFooter).to(equal(testFooters));
- expect(testRequest.timeout).to(equal(testTimeout));
- });
-
- it(@"Should get correctly when initialized with a dictionary", ^ {
- NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameNumberTicks:@(testNumTicks),
- SDLRPCParameterNamePosition:@(testPosition),
- SDLRPCParameterNameSliderHeader:testHeader,
- SDLRPCParameterNameSliderFooter:testFooters,
- SDLRPCParameterNameTimeout:@(testTimeout)},
- SDLRPCParameterNameOperationName:SDLRPCFunctionNameSlider}};
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- testRequest = [[SDLSlider alloc] initWithDictionary:dict];
-#pragma clang diagnostic pop
-
- expect(testRequest.numTicks).to(equal(testNumTicks));
- expect(testRequest.position).to(equal(testPosition));
- expect(testRequest.sliderHeader).to(equal(testHeader));
- expect(testRequest.sliderFooter).to(equal(testFooters));
- expect(testRequest.timeout).to(equal(testTimeout));
- });
+ testRequest.numTicks = @(testNumTicks);
+ testRequest.position = @(testPosition);
+ testRequest.sliderHeader = testHeader;
+ testRequest.sliderFooter = testFooters;
+ testRequest.timeout = @(testTimeout);
+ testRequest.cancelID = @(testCancelID);
- it(@"should correctly initialize with initWithNumTicks:position:", ^{
- testRequest = [[SDLSlider alloc] initWithNumTicks:testNumTicks position:testPosition];
+ expect(testRequest.numTicks).to(equal(testNumTicks));
+ expect(testRequest.position).to(equal(testPosition));
+ expect(testRequest.sliderHeader).to(equal(testHeader));
+ expect(testRequest.sliderFooter).to(equal(testFooters));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.cancelID).to(equal(testCancelID));
- expect(testRequest.numTicks).to(equal(testNumTicks));
- expect(testRequest.position).to(equal(testPosition));
- });
+ expect(testRequest.parameters.count).to(equal(6));
+ });
- it(@"should correctly initialize with initWithNumTicks:position:sliderHeader:sliderFooters:timeout:", ^{
- testRequest = [[SDLSlider alloc] initWithNumTicks:testNumTicks position:testPosition sliderHeader:testHeader sliderFooters:testFooters timeout:testTimeout];
+ it(@"Should return nil if not set", ^ {
+ testRequest = [[SDLSlider alloc] init];
- expect(testRequest.numTicks).to(equal(testNumTicks));
- expect(testRequest.position).to(equal(testPosition));
- expect(testRequest.sliderHeader).to(equal(testHeader));
- expect(testRequest.sliderFooter).to(equal(testFooters));
- expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.numTicks).to(beNil());
+ expect(testRequest.position).to(beNil());
+ expect(testRequest.sliderHeader).to(beNil());
+ expect(testRequest.sliderFooter).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+
+ expect(testRequest.parameters.count).to(equal(0));
+ });
});
- it(@"should correctly initialize with initWithNumTicks:position:sliderHeader:sliderFooter:timeout:", ^{
- testRequest = [[SDLSlider alloc] initWithNumTicks:testNumTicks position:testPosition sliderHeader:testHeader sliderFooter:testFooter timeout:testTimeout];
+ describe(@"Initializing", ^{
+ it(@"Should get correctly when initialized with a dictionary", ^ {
+ NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameNumberTicks:@(testNumTicks),
+ SDLRPCParameterNamePosition:@(testPosition),
+ SDLRPCParameterNameSliderHeader:testHeader,
+ SDLRPCParameterNameSliderFooter:testFooters,
+ SDLRPCParameterNameTimeout:@(testTimeout),
+ SDLRPCParameterNameCancelID:@(testCancelID)
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameSlider}};
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testRequest = [[SDLSlider alloc] initWithDictionary:dict];
+ #pragma clang diagnostic pop
+
+ expect(testRequest.numTicks).to(equal(testNumTicks));
+ expect(testRequest.position).to(equal(testPosition));
+ expect(testRequest.sliderHeader).to(equal(testHeader));
+ expect(testRequest.sliderFooter).to(equal(testFooters));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"should correctly initialize with initWithNumTicks:position:sliderHeader:sliderFooters:timeout:cancelID:", ^{
+ testRequest = [[SDLSlider alloc] initWithNumTicks:testNumTicks position:testPosition sliderHeader:testHeader sliderFooters:testFooters timeout:testTimeout cancelID:testCancelID];
- expect(testRequest.numTicks).to(equal(testNumTicks));
- expect(testRequest.position).to(equal(testPosition));
- expect(testRequest.sliderHeader).to(equal(testHeader));
- expect(testRequest.sliderFooter).to(equal(@[testFooter]));
- expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.numTicks).to(equal(testNumTicks));
+ expect(testRequest.position).to(equal(testPosition));
+ expect(testRequest.sliderHeader).to(equal(testHeader));
+ expect(testRequest.sliderFooter).to(equal(testFooters));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"should correctly initialize with initWithNumTicks:position:", ^{
+ testRequest = [[SDLSlider alloc] initWithNumTicks:testNumTicks position:testPosition];
+
+ expect(testRequest.numTicks).to(equal(testNumTicks));
+ expect(testRequest.position).to(equal(testPosition));
+ expect(testRequest.sliderHeader).to(beNil());
+ expect(testRequest.sliderFooter).to(beNil());
+ expect(testRequest.timeout).to(beNil());
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"should correctly initialize with initWithNumTicks:position:sliderHeader:sliderFooters:timeout:", ^{
+ testRequest = [[SDLSlider alloc] initWithNumTicks:testNumTicks position:testPosition sliderHeader:testHeader sliderFooters:testFooters timeout:testTimeout];
+
+ expect(testRequest.numTicks).to(equal(testNumTicks));
+ expect(testRequest.position).to(equal(testPosition));
+ expect(testRequest.sliderHeader).to(equal(testHeader));
+ expect(testRequest.sliderFooter).to(equal(testFooters));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.cancelID).to(beNil());
+ });
+
+ it(@"should correctly initialize with initWithNumTicks:position:sliderHeader:sliderFooter:timeout:", ^{
+ testRequest = [[SDLSlider alloc] initWithNumTicks:testNumTicks position:testPosition sliderHeader:testHeader sliderFooter:testFooter timeout:testTimeout];
+
+ expect(testRequest.numTicks).to(equal(testNumTicks));
+ expect(testRequest.position).to(equal(testPosition));
+ expect(testRequest.sliderHeader).to(equal(testHeader));
+ expect(testRequest.sliderFooter).to(equal(@[testFooter]));
+ expect(testRequest.timeout).to(equal(testTimeout));
+ expect(testRequest.cancelID).to(beNil());
+ });
});
-
- it(@"Should return nil if not set", ^ {
- testRequest = [[SDLSlider alloc] init];
-
- expect(testRequest.numTicks).to(beNil());
- expect(testRequest.position).to(beNil());
- expect(testRequest.sliderHeader).to(beNil());
- expect(testRequest.sliderFooter).to(beNil());
- expect(testRequest.timeout).to(beNil());
+
+ afterEach(^{
+ expect(testRequest.name).to(equal(SDLRPCFunctionNameSlider));
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLCancelInteractionResponseSpec.m b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLCancelInteractionResponseSpec.m
new file mode 100644
index 000000000..f1f677cba
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLCancelInteractionResponseSpec.m
@@ -0,0 +1,41 @@
+//
+// SDLCancelInteractionResponseSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Nicole on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLCancelInteractionResponse.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLRPCParameterNames.h"
+
+QuickSpecBegin(SDLCancelInteractionResponseSpec)
+
+describe(@"Getter/Setter Tests", ^{
+ __block SDLCancelInteractionResponse *testResponse = nil;
+
+ it(@"Should initialize correctly", ^{
+ testResponse = [[SDLCancelInteractionResponse alloc] init];
+ });
+
+ it(@"Should initialize correctly with a dictionary", ^{
+ NSDictionary *dict = @{SDLRPCParameterNameRequest:@{
+ SDLRPCParameterNameParameters:@{},
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameCancelInteraction}};
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testResponse = [[SDLCancelInteractionResponse alloc] initWithDictionary:dict];
+ #pragma clang diagnostic pop
+ });
+
+ afterEach(^{
+ expect(testResponse.name).to(match(SDLRPCFunctionNameCancelInteraction));
+ expect(testResponse.parameters).to(beEmpty());
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m b/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m
index d1022ac90..e68db2e7d 100644
--- a/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m
+++ b/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m
@@ -19,7 +19,9 @@ describe(@"Individual Enum Value Tests", ^ {
expect(SDLRPCFunctionNameAlert).to(equal(@"Alert"));
expect(SDLRPCFunctionNameAlertManeuver).to(equal(@"AlertManeuver"));
expect(SDLRPCFunctionNameButtonPress).to(equal(@"ButtonPress"));
+ expect(SDLRPCFunctionNameCancelInteraction).to(equal(@"CancelInteraction"));
expect(SDLRPCFunctionNameChangeRegistration).to(equal(@"ChangeRegistration"));
+ expect(SDLRPCFunctionNameCloseApplication).to(equal(@"CloseApplication"));
expect(SDLRPCFunctionNameCreateInteractionChoiceSet).to(equal(@"CreateInteractionChoiceSet"));
expect(SDLRPCFunctionNameDeleteCommand).to(equal(@"DeleteCommand"));
expect(SDLRPCFunctionNameDeleteFile).to(equal(@"DeleteFile"));