summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2020-08-24 11:16:17 -0400
committerJoel Fischer <joeljfischer@gmail.com>2020-08-24 11:16:17 -0400
commita6bb2334cf135d595bf5265231e7e1d0566f3f0d (patch)
tree4e95da090ceffc3d3aa5b73110bf7fac9a2dac04
parent22394a0a7fbf91d4a7ce40d0b8837f747cc47d42 (diff)
parent83634d2f936c616f66ac16f0fb544a4bab248683 (diff)
downloadsdl_ios-a6bb2334cf135d595bf5265231e7e1d0566f3f0d.tar.gz
Merge branch 'develop' into feature/issue-1520-main-menu-updating-and-pagination
# Conflicts: # SmartDeviceLink/SDLFunctionID.m # SmartDeviceLink/SDLImageFieldName.h # SmartDeviceLink/SDLImageFieldName.m # SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m
-rw-r--r--Example Apps/Example ObjC/AlertManager.h24
-rw-r--r--Example Apps/Example ObjC/AlertManager.m43
-rw-r--r--Example Apps/Example ObjC/AudioManager.m5
-rw-r--r--Example Apps/Example ObjC/ButtonManager.h2
-rw-r--r--Example Apps/Example ObjC/ButtonManager.m94
-rw-r--r--Example Apps/Example ObjC/MenuManager.m24
-rw-r--r--Example Apps/Example ObjC/VehicleDataManager.m10
-rw-r--r--Example Apps/Example Swift/AlertManager.swift60
-rw-r--r--Example Apps/Example Swift/AudioManager.swift9
-rw-r--r--Example Apps/Example Swift/ButtonManager.swift107
-rw-r--r--Example Apps/Example Swift/MenuManager.swift26
-rw-r--r--Example Apps/Example Swift/ProxyManager.swift2
-rw-r--r--Example Apps/Example Swift/VehicleDataManager.swift14
-rw-r--r--Example Apps/Shared/AppConstants.h31
-rw-r--r--Example Apps/Shared/AppConstants.m33
-rw-r--r--SmartDeviceLink-iOS.podspec3
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj36
-rw-r--r--SmartDeviceLink.podspec3
-rw-r--r--SmartDeviceLink/SDLCancelInteraction.h55
-rw-r--r--SmartDeviceLink/SDLCancelInteraction.m46
-rw-r--r--SmartDeviceLink/SDLFunctionID.m2
-rw-r--r--SmartDeviceLink/SDLImageFieldName.h8
-rw-r--r--SmartDeviceLink/SDLImageFieldName.m1
-rw-r--r--SmartDeviceLink/SDLNotificationConstants.h11
-rw-r--r--SmartDeviceLink/SDLNotificationConstants.m4
-rw-r--r--SmartDeviceLink/SDLOnSubtleAlertPressed.h46
-rw-r--r--SmartDeviceLink/SDLOnSubtleAlertPressed.m56
-rw-r--r--SmartDeviceLink/SDLRPCFunctionNames.h6
-rw-r--r--SmartDeviceLink/SDLRPCFunctionNames.m2
-rw-r--r--SmartDeviceLink/SDLSubtleAlert.h103
-rw-r--r--SmartDeviceLink/SDLSubtleAlert.m130
-rw-r--r--SmartDeviceLink/SDLSubtleAlertResponse.h56
-rw-r--r--SmartDeviceLink/SDLSubtleAlertResponse.m73
-rw-r--r--SmartDeviceLink/SDLTextFieldName.h55
-rw-r--r--SmartDeviceLink/SDLTextFieldName.m37
-rw-r--r--SmartDeviceLink/SmartDeviceLink.h3
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m1
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m3
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnSubtleAlertPressedSpec.m29
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m14
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSubtleAlertSpec.m107
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLSubtleAlertResponseSpec.m54
-rw-r--r--SmartDeviceLink_Example/SubscribeButtonManager.m3
-rw-r--r--SmartDeviceLink_Example/SubscribeButtonManager.swift7
-rw-r--r--generator/transformers/common_producer.py62
45 files changed, 1280 insertions, 220 deletions
diff --git a/Example Apps/Example ObjC/AlertManager.h b/Example Apps/Example ObjC/AlertManager.h
index 10508261a..d7b42b655 100644
--- a/Example Apps/Example ObjC/AlertManager.h
+++ b/Example Apps/Example ObjC/AlertManager.h
@@ -9,20 +9,26 @@
#import <Foundation/Foundation.h>
@class SDLAlert;
+@class SDLManager;
+@class SDLSubtleAlert;
NS_ASSUME_NONNULL_BEGIN
@interface AlertManager : NSObject
-/**
- 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;
+/// Sends an alert with up to two lines of text, an image, and a close button that will dismiss the alert when tapped.
+/// @param imageName The name of the image to upload
+/// @param textField1 The first line of text in the alert
+/// @param textField2 The second line of text in the alert
+/// @param sdlManager The SDLManager
++ (void)sendAlertWithManager:(SDLManager *)sdlManager image:(nullable NSString *)imageName textField1:(NSString *)textField1 textField2:(nullable NSString *)textField2;
+
+/// Sends a subtle alert with up to two lines of text, and an image.
+/// @param imageName The name of the image to upload
+/// @param textField1 The first line of text in the alert
+/// @param textField2 The second line of text in the alert
+/// @param sdlManager The SDLManager
++ (void)sendSubtleAlertWithManager:(SDLManager *)sdlManager image:(nullable NSString *)imageName textField1:(NSString *)textField1 textField2:(nullable NSString *)textField2;
@end
diff --git a/Example Apps/Example ObjC/AlertManager.m b/Example Apps/Example ObjC/AlertManager.m
index 3efbba544..9ee13fcdd 100644
--- a/Example Apps/Example ObjC/AlertManager.m
+++ b/Example Apps/Example ObjC/AlertManager.m
@@ -14,12 +14,47 @@ NS_ASSUME_NONNULL_BEGIN
@implementation AlertManager
-+ (SDLSoftButton *)sdlex_okSoftButton {
- return [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:AlertOKButtonText image:nil highlighted:YES buttonId:1 systemAction:nil handler:nil];
++ (void)sendAlertWithManager:(SDLManager *)sdlManager image:(nullable NSString *)imageName textField1:(NSString *)textField1 textField2:(nullable NSString *)textField2 {
+ SDLSoftButton *okSoftButton = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:AlertOKButtonText image:nil highlighted:YES buttonId:1 systemAction:nil handler:nil];
+ SDLAlert *alert = [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2 alertText3:nil softButtons:@[okSoftButton] playTone:YES ttsChunks:nil duration:5000 progressIndicator:NO alertIcon:nil cancelID:0];
+
+ if (imageName == nil) {
+ [sdlManager sendRequest:alert];
+ } else {
+ [self sdlex_sendImageWithName:imageName sdlManager:sdlManager completionHandler:^(BOOL success, NSString * _Nullable artworkName) {
+ if (success) {
+ alert.alertIcon = [[SDLImage alloc] initWithName:artworkName isTemplate:YES];
+ }
+ [sdlManager sendRequest:alert];
+ }];
+ }
}
-+ (SDLAlert *)alertWithMessageAndCloseButton:(NSString *)textField1 textField2:(nullable NSString *)textField2 iconName:(nullable NSString *)iconName {
- 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];
++ (void)sendSubtleAlertWithManager:(SDLManager *)sdlManager image:(nullable NSString *)imageName textField1:(NSString *)textField1 textField2:(nullable NSString *)textField2 {
+ SDLSubtleAlert *subtleAlert = [[SDLSubtleAlert alloc] initWithAlertText1:textField1 alertText2:textField2 alertIcon:nil ttsChunks:nil duration:nil softButtons:nil cancelID:0];
+
+ if (imageName == nil) {
+ [sdlManager sendRequest:subtleAlert];
+ } else {
+ [self sdlex_sendImageWithName:imageName sdlManager:sdlManager completionHandler:^(BOOL success, NSString * _Nullable artworkName) {
+ if (success) {
+ subtleAlert.alertIcon = [[SDLImage alloc] initWithName:artworkName isTemplate:YES];
+ }
+ [sdlManager sendRequest:subtleAlert];
+ }];
+ }
+}
+
+/// Helper method for uploading an image before it is shown in an alert
+/// @param imageName The name of the image to upload
+/// @param sdlManager The SDLManager
+/// @param completionHandler Handler called when the artwork has finished uploading with the success of the upload and the name of the uploaded image.
++ (void)sdlex_sendImageWithName:(NSString *)imageName sdlManager:(SDLManager *)sdlManager completionHandler:(void (^)(BOOL success, NSString * _Nonnull artworkName))completionHandler {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:[[UIImage imageNamed:imageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG];
+
+ [sdlManager.fileManager uploadArtwork:artwork completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ return completionHandler(success, artworkName);
+ }];
}
@end
diff --git a/Example Apps/Example ObjC/AudioManager.m b/Example Apps/Example ObjC/AudioManager.m
index cd6ec4ecf..dc1c77e41 100644
--- a/Example Apps/Example ObjC/AudioManager.m
+++ b/Example Apps/Example ObjC/AudioManager.m
@@ -7,6 +7,7 @@
//
#import "AlertManager.h"
+#import "AppConstants.h"
#import "AudioManager.h"
#import <AVFoundation/AVFoundation.h>
#import "SDLLogMacros.h"
@@ -86,7 +87,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)startRecording {
if (self.speechRecognitionAuthState != SpeechRecognitionAuthStateAuthorized) {
SDLLogW(@"This app does not have permission to access the Speech Recognition API");
- [self.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"You must give this app permission to access Speech Recognition" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:self.sdlManager image:nil textField1:AlertSpeechPermissionsWarningText textField2:nil];
return;
}
@@ -155,7 +156,7 @@ NS_ASSUME_NONNULL_BEGIN
// The `PerformAudioPassThru` timed out or the "Done" button was pressed in the pop-up.
SDLLogD(@"Audio Pass Thru ended successfully");
NSString *alertMessage = [NSString stringWithFormat:@"You said: %@", weakSelf.speechTranscription.length == 0 ? @"No speech detected" : weakSelf.speechTranscription];
- [weakSelf.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:alertMessage textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:weakSelf.sdlManager image:nil textField1:alertMessage textField2:nil];
} else if ([resultCode isEqualToEnum:SDLResultAborted]) {
// The "Cancel" button was pressed in the pop-up. Ignore this audio pass thru.
SDLLogD(@"Audio recording canceled");
diff --git a/Example Apps/Example ObjC/ButtonManager.h b/Example Apps/Example ObjC/ButtonManager.h
index 867f50c7c..256ea8ee4 100644
--- a/Example Apps/Example ObjC/ButtonManager.h
+++ b/Example Apps/Example ObjC/ButtonManager.h
@@ -18,12 +18,12 @@ typedef void(^RefreshUIHandler)(void);
@interface ButtonManager : NSObject
@property (assign, nonatomic, getter=isTextEnabled, readonly) BOOL textEnabled;
-@property (assign, nonatomic, getter=isHexagonEnabled, readonly) BOOL toggleEnabled;
@property (assign, nonatomic, getter=areImagesEnabled, readonly) BOOL imagesEnabled;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithManager:(SDLManager *)manager refreshUIHandler:(RefreshUIHandler)refreshUIHandler;
+/// An array of all the soft buttons
- (NSArray<SDLSoftButtonObject *> *)allScreenSoftButtons;
@end
diff --git a/Example Apps/Example ObjC/ButtonManager.m b/Example Apps/Example ObjC/ButtonManager.m
index 1809249db..4ca86be0a 100644
--- a/Example Apps/Example ObjC/ButtonManager.m
+++ b/Example Apps/Example ObjC/ButtonManager.m
@@ -19,7 +19,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) SDLManager *sdlManager;
@property (assign, nonatomic, getter=isTextEnabled, readwrite) BOOL textEnabled;
-@property (assign, nonatomic, getter=isHexagonEnabled, readwrite) BOOL toggleEnabled;
@property (assign, nonatomic, getter=areImagesEnabled, readwrite) BOOL imagesEnabled;
@end
@@ -37,7 +36,6 @@ NS_ASSUME_NONNULL_BEGIN
_textEnabled = YES;
_imagesEnabled = YES;
- _toggleEnabled = YES;
return self;
}
@@ -52,61 +50,73 @@ NS_ASSUME_NONNULL_BEGIN
- (void)setImagesEnabled:(BOOL)imagesEnabled {
_imagesEnabled = imagesEnabled;
-
- SDLSoftButtonObject *object = [self.sdlManager.screenManager softButtonObjectNamed:AlertSoftButton];
- [object transitionToNextState];
-
if (self.refreshUIHandler == nil) { return; }
self.refreshUIHandler();
}
-- (void)setToggleEnabled:(BOOL)toggleEnabled {
- _toggleEnabled = toggleEnabled;
- SDLSoftButtonObject *object = [self.sdlManager.screenManager softButtonObjectNamed:ToggleSoftButton];
- [object transitionToStateNamed:(toggleEnabled ? ToggleSoftButtonImageOnState : ToggleSoftButtonImageOffState)];
+#pragma mark - Getters
+
+- (BOOL)sdlex_isSubtleAlertAllowed {
+ return [self.sdlManager.permissionManager isRPCNameAllowed:SDLRPCFunctionNameSubtleAlert];
+}
+
+- (BOOL)sdlex_isAlertAllowed {
+ return [self.sdlManager.permissionManager isRPCNameAllowed:SDLRPCFunctionNameAlert];
}
#pragma mark - Custom Soft Buttons
- (NSArray<SDLSoftButtonObject *> *)allScreenSoftButtons {
- return @[[self sdlex_softButtonAlertWithManager:self.sdlManager], [self sdlex_softButtonToggleWithManager:self.sdlManager], [self sdlex_softButtonTextVisibleWithManager:self.sdlManager], [self sdlex_softButtonImagesVisibleWithManager:self.sdlManager]];
+ return @[[self sdlex_softButtonAlert], [self sdlex_softButtonSubtleAlert], [self sdlex_softButtonTextVisible], [self sdlex_softButtonImagesVisible]];
}
-- (SDLSoftButtonObject *)sdlex_softButtonAlertWithManager:(SDLManager *)manager {
- SDLSoftButtonState *alertImageAndTextState = [[SDLSoftButtonState alloc] initWithStateName:AlertSoftButtonImageState text:AlertSoftButtonText artwork:[SDLArtwork artworkWithImage:[[UIImage imageNamed:CarBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] name:CarBWIconImageName asImageFormat:SDLArtworkImageFormatPNG]];
- SDLSoftButtonState *alertTextState = [[SDLSoftButtonState alloc] initWithStateName:AlertSoftButtonTextState text:AlertSoftButtonText image:nil];
+/// Returns a soft button that shows an alert when tapped.
+/// @returns A SDLSoftButtonObject object
+- (SDLSoftButtonObject *)sdlex_softButtonAlert {
+ SDLSoftButtonState *imageAndTextState = [[SDLSoftButtonState alloc] initWithStateName:AlertSoftButtonImageAndTextState text:AlertSoftButtonText artwork:[SDLArtwork artworkWithImage:[[UIImage imageNamed:AlertBWIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG]];
+ SDLSoftButtonState *textState = [[SDLSoftButtonState alloc] initWithStateName:AlertSoftButtonTextState text:AlertSoftButtonText image:nil];
__weak typeof(self) weakself = self;
- SDLSoftButtonObject *alertSoftButton = [[SDLSoftButtonObject alloc] initWithName:AlertSoftButton states:@[alertImageAndTextState, alertTextState] initialStateName:alertImageAndTextState.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {
+ SDLSoftButtonObject *alertSoftButton = [[SDLSoftButtonObject alloc] initWithName:AlertSoftButton states:@[imageAndTextState, textState] initialStateName:imageAndTextState.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {
if (buttonPress == nil) { return; }
- [weakself.sdlManager.fileManager uploadArtwork:[SDLArtwork artworkWithImage:[UIImage imageNamed:CarBWIconImageName] asImageFormat:SDLArtworkImageFormatPNG] completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
- [weakself.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"You pushed the soft button!" textField2:nil iconName:artworkName] withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
- NSLog(@"ALERT req: %@, res: %@, err: %@", request, response, error);
- }];
- }];
-
- SDLLogD(@"Star icon soft button press fired");
+ if (self.sdlex_isAlertAllowed) {
+ [AlertManager sendAlertWithManager:weakself.sdlManager image:CarBWIconImageName textField1:AlertMessageText textField2:nil];
+ } else if (self.sdlex_isSubtleAlertAllowed) {
+ [AlertManager sendSubtleAlertWithManager:weakself.sdlManager image:CarBWIconImageName textField1:AlertMessageText textField2:nil];
+ } else {
+ SDLLogW(@"The module does not support the Alert request or the Subtle Alert request");
+ }
}];
return alertSoftButton;
}
-- (SDLSoftButtonObject *)sdlex_softButtonToggleWithManager:(SDLManager *)manager {
- SDLSoftButtonState *toggleImageOnState = [[SDLSoftButtonState alloc] initWithStateName:ToggleSoftButtonImageOnState text:nil image:[[UIImage imageNamed:ToggleOnBWIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
- SDLSoftButtonState *toggleImageOffState = [[SDLSoftButtonState alloc] initWithStateName:ToggleSoftButtonImageOffState text:nil image:[[UIImage imageNamed:ToggleOffBWIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
+/// Returns a soft button that shows a subtle alert when tapped. If the subtle alert is not supported, then a regular alert is shown.
+/// @returns A SDLSoftButtonObject object
+- (SDLSoftButtonObject *)sdlex_softButtonSubtleAlert {
+ SDLSoftButtonState *imageAndTextState = [[SDLSoftButtonState alloc] initWithStateName:SubtleAlertSoftButtonImageAndTextState text:SubtleAlertSoftButtonText artwork:[SDLArtwork artworkWithImage:[[UIImage imageNamed:BatteryFullBWIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG]];
+ SDLSoftButtonState *textState = [[SDLSoftButtonState alloc] initWithStateName:SubtleAlertSoftButtonTextState text:SubtleAlertSoftButtonText image:nil];
__weak typeof(self) weakself = self;
- SDLSoftButtonObject *toggleButton = [[SDLSoftButtonObject alloc] initWithName:ToggleSoftButton states:@[toggleImageOnState, toggleImageOffState] initialStateName:toggleImageOnState.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {
+ SDLSoftButtonObject *subtleAlertSoftButton = [[SDLSoftButtonObject alloc] initWithName:SubtleAlertSoftButton states:@[imageAndTextState, textState] initialStateName:imageAndTextState.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {
if (buttonPress == nil) { return; }
- weakself.toggleEnabled = !weakself.toggleEnabled;
- SDLLogD(@"Toggle icon button press fired %d", self.toggleEnabled);
+
+ if (self.sdlex_isSubtleAlertAllowed) {
+ [AlertManager sendSubtleAlertWithManager:weakself.sdlManager image:BatteryEmptyBWIconName textField1:SubtleAlertHeaderText textField2:SubtleAlertSubheaderText];
+ } else if (self.sdlex_isAlertAllowed) {
+ [AlertManager sendAlertWithManager:weakself.sdlManager image:BatteryEmptyBWIconName textField1:SubtleAlertHeaderText textField2:SubtleAlertSubheaderText];
+ } else {
+ SDLLogW(@"The module does not support the Alert request or the Subtle Alert request");
+ }
}];
- return toggleButton;
+ return subtleAlertSoftButton;
}
-- (SDLSoftButtonObject *)sdlex_softButtonTextVisibleWithManager:(SDLManager *)manager {
+/// Returns a soft button that toggles the textfield visibility state.
+/// @returns A SDLSoftButtonObject object
+- (SDLSoftButtonObject *)sdlex_softButtonTextVisible {
SDLSoftButtonState *textOnState = [[SDLSoftButtonState alloc] initWithStateName:TextVisibleSoftButtonTextOnState text:TextVisibleSoftButtonTextOnText image:nil];
SDLSoftButtonState *textOffState = [[SDLSoftButtonState alloc] initWithStateName:TextVisibleSoftButtonTextOffState text:TextVisibleSoftButtonTextOffText image:nil];
@@ -115,34 +125,34 @@ NS_ASSUME_NONNULL_BEGIN
if (buttonPress == nil) { return; }
weakself.textEnabled = !weakself.textEnabled;
- SDLSoftButtonObject *object = [weakself.sdlManager.screenManager softButtonObjectNamed:TextVisibleSoftButton];
- [object transitionToNextState];
- SDLLogD(@"Text visibility soft button press fired %d", weakself.textEnabled);
+ SDLSoftButtonObject *textVisibleSoftButton = [weakself.sdlManager.screenManager softButtonObjectNamed:TextVisibleSoftButton];
+ [textVisibleSoftButton transitionToNextState];
}];
return textButton;
}
-- (SDLSoftButtonObject *)sdlex_softButtonImagesVisibleWithManager:(SDLManager *)manager {
+/// Returns a soft button that toggles the image visibility state.
+/// @returns A SDLSoftButtonObject object
+- (SDLSoftButtonObject *)sdlex_softButtonImagesVisible {
SDLSoftButtonState *imagesOnState = [[SDLSoftButtonState alloc] initWithStateName:ImagesVisibleSoftButtonImageOnState text:ImagesVisibleSoftButtonImageOnText image:nil];
SDLSoftButtonState *imagesOffState = [[SDLSoftButtonState alloc] initWithStateName:ImagesVisibleSoftButtonImageOffState text:ImagesVisibleSoftButtonImageOffText image:nil];
__weak typeof(self) weakself = self;
SDLSoftButtonObject *imagesButton = [[SDLSoftButtonObject alloc] initWithName:ImagesVisibleSoftButton states:@[imagesOnState, imagesOffState] initialStateName:imagesOnState.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {
- if (buttonPress == nil) {
- return;
- }
+ if (buttonPress == nil) { return; }
weakself.imagesEnabled = !weakself.imagesEnabled;
- SDLSoftButtonObject *object = [weakself.sdlManager.screenManager softButtonObjectNamed:ImagesVisibleSoftButton];
- [object transitionToNextState];
+ SDLSoftButtonObject *imagesVisibleSoftButton = [weakself.sdlManager.screenManager softButtonObjectNamed:ImagesVisibleSoftButton];
+ [imagesVisibleSoftButton transitionToNextState];
- SDLSoftButtonObject *textButton = [weakself.sdlManager.screenManager softButtonObjectNamed:TextVisibleSoftButton];
- [textButton transitionToNextState];
+ SDLSoftButtonObject *alertSoftButton = [weakself.sdlManager.screenManager softButtonObjectNamed:AlertSoftButton];
+ [alertSoftButton transitionToNextState];
- SDLLogD(@"Image visibility soft button press fired %d", weakself.imagesEnabled);
+ SDLSoftButtonObject *subtleAlertSoftButton = [weakself.sdlManager.screenManager softButtonObjectNamed:SubtleAlertSoftButton];
+ [subtleAlertSoftButton transitionToNextState];
}];
return imagesButton;
diff --git a/Example Apps/Example ObjC/MenuManager.m b/Example Apps/Example ObjC/MenuManager.m
index 00a05b377..d1c6f46c6 100644
--- a/Example Apps/Example ObjC/MenuManager.m
+++ b/Example Apps/Example ObjC/MenuManager.m
@@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (SDLMenuCell *)sdlex_menuCellDialNumberWithManager:(SDLManager *)manager {
return [[SDLMenuCell alloc] initWithTitle:ACDialPhoneNumberMenuName icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:PhoneBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] voiceCommands:@[ACDialPhoneNumberMenuName] handler:^(SDLTriggerSource _Nonnull triggerSource) {
if (![RPCPermissionsManager isDialNumberRPCAllowedWithManager:manager]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"This app does not have the required permissions to dial a number" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertDialNumberPermissionsWarningText textField2:nil];
return;
}
@@ -100,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLSetDisplayLayout* display = [[SDLSetDisplayLayout alloc] initWithPredefinedLayout:SDLPredefinedLayoutNonMedia];
[manager sendRequest:display withResponseHandler:^(SDLRPCRequest *request, SDLRPCResponse *response, NSError *error) {
if (!response.success) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:errorMessage textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:errorMessage textField2:nil];
}
}];
}];
@@ -111,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLSetDisplayLayout* display = [[SDLSetDisplayLayout alloc] initWithPredefinedLayout:SDLPredefinedLayoutGraphicWithText];
[manager sendRequest:display withResponseHandler:^(SDLRPCRequest *request, SDLRPCResponse *response, NSError *error) {
if (!response.success) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:errorMessage textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:errorMessage textField2:nil];
}
}];
}];
@@ -124,7 +124,7 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableArray *submenuItems = [NSMutableArray array];
for (int i = 0; i < 75; i++) {
SDLMenuCell *cell = [[SDLMenuCell alloc] initWithTitle:[NSString stringWithFormat:@"%@ %i", ACSubmenuItemMenuName, i] icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:MenuBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"You selected %@ %i", ACSubmenuItemMenuName, i] textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:[NSString stringWithFormat:@"You selected %@ %i", ACSubmenuItemMenuName, i] textField2:nil];
}];
[submenuItems addObject:cell];
}
@@ -138,11 +138,11 @@ NS_ASSUME_NONNULL_BEGIN
[manager sendRequest:sliderRPC withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
if(![response.resultCode isEqualToEnum:SDLResultSuccess]) {
if ([response.resultCode isEqualToEnum:SDLResultTimedOut]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Slider timed out" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertSliderTimedOutWarningText textField2:nil];
} else if ([response.resultCode isEqualToEnum:SDLResultAborted]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Slider cancelled" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertSliderCancelledWarningText textField2:nil];
} else {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Slider could not be displayed" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertSliderGeneralWarningText textField2:nil];
}
}
}];
@@ -155,11 +155,11 @@ NS_ASSUME_NONNULL_BEGIN
[manager sendRequest:messageRPC withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
if(![response.resultCode isEqualToEnum:SDLResultSuccess]) {
if ([response.resultCode isEqualToEnum:SDLResultTimedOut]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Scrollable Message timed out" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertScrollableMessageTimedOutWarningText textField2:nil];
} else if ([response.resultCode isEqualToEnum:SDLResultAborted]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Scrollable Message cancelled" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertScrollableMessageCancelledWarningText textField2:nil];
} else {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Scrollable Message could not be displayed" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertScrollableMessageGeneralWarningText textField2:nil];
}
}
}];
@@ -170,13 +170,13 @@ NS_ASSUME_NONNULL_BEGIN
+ (SDLVoiceCommand *)sdlex_voiceCommandStartWithManager:(SDLManager *)manager {
return [[SDLVoiceCommand alloc] initWithVoiceCommands:@[VCStop] handler:^{
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"%@ voice command selected!", VCStop] textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:[NSString stringWithFormat:@"%@ voice command selected!", VCStop] textField2:nil];
}];
}
+ (SDLVoiceCommand *)sdlex_voiceCommandStopWithManager:(SDLManager *)manager {
return [[SDLVoiceCommand alloc] initWithVoiceCommands:@[VCStart] handler:^{
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"%@ voice command selected!", VCStart] textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:[NSString stringWithFormat:@"%@ voice command selected!", VCStart] textField2:nil];
}];
}
diff --git a/Example Apps/Example ObjC/VehicleDataManager.m b/Example Apps/Example ObjC/VehicleDataManager.m
index bcbf1f362..a109d4b6b 100644
--- a/Example Apps/Example ObjC/VehicleDataManager.m
+++ b/Example Apps/Example ObjC/VehicleDataManager.m
@@ -138,7 +138,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)getAllVehicleDataWithManager:(SDLManager *)manager triggerSource:(SDLTriggerSource)triggerSource vehicleDataType:(NSString *)vehicleDataType {
SDLLogD(@"Checking if app has permission to access vehicle data...");
if (![manager.permissionManager isRPCNameAllowed:SDLRPCFunctionNameGetVehicleData]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"This app does not have the required permissions to access vehicle data" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertVehicleDataPermissionsWarningText textField2:nil];
return;
}
@@ -153,7 +153,7 @@ NS_ASSUME_NONNULL_BEGIN
[manager sendRequest:getAllVehicleData withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
if (error || ![response isKindOfClass:SDLGetVehicleDataResponse.class]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Something went wrong while getting vehicle data" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertVehicleDataGeneralWarningText textField2:nil];
return;
}
@@ -183,7 +183,7 @@ NS_ASSUME_NONNULL_BEGIN
alertMessage = [TextValidator validateText:alertMessage length:200];
if ([triggerSource isEqualToEnum:SDLTriggerSourceMenu]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:alertTitle textField2:alertMessage iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:alertTitle textField2:alertMessage];
} else {
NSString *spokenAlert = alertMessage ?: alertTitle;
[manager sendRequest:[[SDLSpeak alloc] initWithTTS:spokenAlert]];
@@ -271,7 +271,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLLogD(@"Checking phone call capability");
[manager.systemCapabilityManager updateCapabilityType:SDLSystemCapabilityTypePhoneCall completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) {
if (!systemCapabilityManager.phoneCapability) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"The head unit does not support the phone call capability" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertDialNumberPermissionsWarningText textField2:nil];
return;
}
@@ -279,7 +279,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLLogD(@"Dialing phone number %@", phoneNumber);
[self sdlex_dialPhoneNumber:phoneNumber manager:manager];
} else {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"The dial number feature is unavailable for this head unit" textField2:nil iconName:nil]];
+ [AlertManager sendAlertWithManager:manager image:nil textField1:AlertDialNumberUnavailableWarningText textField2:nil];
}
}];
}
diff --git a/Example Apps/Example Swift/AlertManager.swift b/Example Apps/Example Swift/AlertManager.swift
index 718210777..9e37dd1c5 100644
--- a/Example Apps/Example Swift/AlertManager.swift
+++ b/Example Apps/Example Swift/AlertManager.swift
@@ -10,18 +10,58 @@ import Foundation
import SmartDeviceLink
class AlertManager {
- private class var okSoftButton: SDLSoftButton {
- return SDLSoftButton(type: .text, text: AlertOKButtonText, image: nil, highlighted: true, buttonId: 1, systemAction: nil, handler: nil)
+ /// Sends an alert with up to two lines of text, an image, and a close button that will dismiss the alert when tapped.
+ /// - Parameters:
+ /// - imageName: The name of the image to upload
+ /// - textField1: The first line of text in the alert
+ /// - textField2: The second line of text in the alert
+ /// - sdlManager: The SDLManager
+ class func sendAlert(imageName: String? = nil, textField1: String, textField2: String? = nil, sdlManager: SDLManager) {
+ let okSoftButton = SDLSoftButton(type: .text, text: AlertOKButtonText, image: nil, highlighted: true, buttonId: 1, systemAction: nil, handler: nil)
+ let alert = SDLAlert(alertText1: textField1, alertText2: textField2, alertText3: nil, softButtons: [okSoftButton], playTone: true, ttsChunks: nil, duration: 5000, progressIndicator: false, alertIcon: nil, cancelID: 0)
+
+ if let imageName = imageName {
+ sendImage(imageName, sdlManager: sdlManager) { (success, artworkName) in
+ if success {
+ alert.alertIcon = SDLImage(name: artworkName, isTemplate: true)
+ }
+ sdlManager.send(alert)
+ }
+ } else {
+ sdlManager.send(alert)
+ }
+ }
+
+ /// Sends a subtle alert with up to two lines of text, and an image.
+ /// - Parameters:
+ /// - imageName: The name of the image to upload
+ /// - textField1: The first line of text in the alert
+ /// - textField2: The second line of text in the alert
+ /// - sdlManager: The SDLManager
+ class func sendSubtleAlert(imageName: String? = nil, textField1: String, textField2: String? = nil, sdlManager: SDLManager) {
+ let subtleAlert = SDLSubtleAlert(alertText1: textField1, alertText2: textField2, alertIcon: nil, ttsChunks: nil, duration: nil, softButtons: nil, cancelID: NSNumber(0))
+
+ if let imageName = imageName {
+ sendImage(imageName, sdlManager: sdlManager) { (success, artworkName) in
+ if success {
+ subtleAlert.alertIcon = SDLImage(name: artworkName, isTemplate: true)
+ }
+ sdlManager.send(subtleAlert)
+ }
+ } else {
+ sdlManager.send(subtleAlert)
+ }
}
- /// Creates an alert with up to two lines of text, an image, and a close button that will dismiss the alert when tapped.
- ///
+ /// Helper method for uploading an image before it is shown in an alert
/// - 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
- /// - 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, softButtons: [okSoftButton], playTone: true, ttsChunks: nil, duration: 5000, progressIndicator: false, alertIcon: (iconName != nil) ? SDLImage(name: iconName!, isTemplate: true) : nil, cancelID: 0)
+ /// - imageName: The name of the image to upload
+ /// - sdlManager: The SDLManager
+ /// - completionHandler: Handler called when the artwork has finished uploading with the success of the upload and the name of the uploaded image.
+ private class func sendImage(_ imageName: String, sdlManager: SDLManager, completionHandler: @escaping ((_ success: Bool, _ artwork: String) -> ())) {
+ let artwork = SDLArtwork(image: UIImage(named: imageName)!.withRenderingMode(.alwaysTemplate), persistent: false, as: .PNG)
+ sdlManager.fileManager.upload(artwork: artwork) { (success, artworkName, bytesAvailable, error) in
+ return completionHandler(success, artworkName)
+ }
}
}
diff --git a/Example Apps/Example Swift/AudioManager.swift b/Example Apps/Example Swift/AudioManager.swift
index 6ea7e8813..cfbc4538f 100644
--- a/Example Apps/Example Swift/AudioManager.swift
+++ b/Example Apps/Example Swift/AudioManager.swift
@@ -60,7 +60,7 @@ class AudioManager: NSObject {
func startRecording() {
guard speechRecognitionAuthState == .authorized else {
SDLLog.w("This app does not have permission to access the Speech Recognition API")
- sdlManager.send(AlertManager.alertWithMessageAndCloseButton("You must give this app permission to access Speech Recognition"))
+ AlertManager.sendAlert(textField1: AlertSpeechPermissionsWarningText, sdlManager: sdlManager)
return
}
@@ -106,20 +106,19 @@ private extension AudioManager {
/// Called when `PerformAudioPassThru` request times out or when a `EndAudioPassThru` request is sent
var audioPassThruEndedHandler: SDLResponseHandler? {
return { [weak self] (request, response, error) in
- guard let response = response else { return }
+ guard let self = self, let response = response else { return }
switch response.resultCode {
case .success: // The `PerformAudioPassThru` timed out or the "Done" button was pressed in the pop-up.
SDLLog.d("Audio Pass Thru ended successfully")
- guard let speechTranscription = self?.speechTranscription else { return }
- self?.sdlManager.send(AlertManager.alertWithMessageAndCloseButton("You said: \(speechTranscription.isEmpty ? "No speech detected" : speechTranscription)"))
+ AlertManager.sendAlert(textField1: "You said: \(self.speechTranscription.isEmpty ? "No speech detected" : self.speechTranscription)", sdlManager: self.sdlManager)
case .aborted: // The "Cancel" button was pressed in the pop-up. Ignore this audio pass thru.
SDLLog.d("Audio recording canceled")
default:
SDLLog.d("Audio recording not successful: \(response.resultCode)")
}
- self?.stopSpeechRecognitionTask()
+ self.stopSpeechRecognitionTask()
}
}
diff --git a/Example Apps/Example Swift/ButtonManager.swift b/Example Apps/Example Swift/ButtonManager.swift
index e0953accc..02d3f7962 100644
--- a/Example Apps/Example Swift/ButtonManager.swift
+++ b/Example Apps/Example Swift/ButtonManager.swift
@@ -16,7 +16,7 @@ class ButtonManager: NSObject {
fileprivate let sdlManager: SDLManager!
fileprivate var refreshUIHandler: RefreshUIHandler?
- /// SDL UI textfields are visible if true; hidden if false
+ /// Textfields are visible if true; hidden if false
public fileprivate(set) var textEnabled: Bool {
didSet {
guard let refreshUIHandler = refreshUIHandler else { return }
@@ -24,20 +24,20 @@ class ButtonManager: NSObject {
}
}
- /// SDL UI images are visible if true; hidden if false
+ /// UI images are visible if true; hidden if false
public fileprivate(set) var imagesEnabled: Bool {
didSet {
- guard let refreshUIHandler = refreshUIHandler, let alertSoftButton = sdlManager.screenManager.softButtonObjectNamed(AlertSoftButton) else { return }
- alertSoftButton.transitionToNextState()
+ guard let refreshUIHandler = refreshUIHandler else { return }
refreshUIHandler()
}
}
- /// Keeps track of the toggle soft button current state. The image or text changes when the button is selected
- fileprivate var toggleEnabled: Bool {
- didSet {
- guard let hexagonSoftButton = sdlManager.screenManager.softButtonObjectNamed(ToggleSoftButton), hexagonSoftButton.transition(toState: toggleEnabled ? ToggleSoftButtonImageOnState : ToggleSoftButtonImageOffState) else { return }
- }
+ private var isSubtleAlertAllowed: Bool {
+ return sdlManager.permissionManager.isRPCNameAllowed(.subtleAlert)
+ }
+
+ private var isAlertAllowed: Bool {
+ return sdlManager.permissionManager.isRPCNameAllowed(.alert)
}
init(sdlManager: SDLManager, updateScreenHandler: RefreshUIHandler? = nil) {
@@ -45,54 +45,56 @@ class ButtonManager: NSObject {
self.refreshUIHandler = updateScreenHandler
textEnabled = true
imagesEnabled = true
- toggleEnabled = true
- super.init()
}
- /// Creates and returns an array of all soft buttons for the UI
+ /// An array of all the soft buttons
///
/// - Parameter manager: The SDL Manager
/// - Returns: An array of all soft buttons for the UI
- func allScreenSoftButtons(with manager: SDLManager) -> [SDLSoftButtonObject] {
- return [softButtonAlert(with: manager), softButtonToggle(), softButtonTextVisible(), softButtonImagesVisible()]
+ func allScreenSoftButtons() -> [SDLSoftButtonObject] {
+ return [softButtonAlert, softButtonSubtleAlert, softButtonTextVisible, softButtonImagesVisible]
}
}
// MARK: - Custom Soft Buttons
-private extension ButtonManager {
+extension ButtonManager {
/// Returns a soft button that shows an alert when tapped.
- ///
- /// - Parameter manager: The SDL Manager for showing the alert
- /// - Returns: A soft button
- func softButtonAlert(with manager: SDLManager) -> SDLSoftButtonObject {
- let imageSoftButtonState = SDLSoftButtonState(stateName: AlertSoftButtonImageState, text: nil, image: UIImage(named: AlertBWIconName)?.withRenderingMode(.alwaysTemplate))
- let textSoftButtonState = SDLSoftButtonState(stateName: AlertSoftButtonTextState, text: AlertSoftButtonText, image: nil)
- return SDLSoftButtonObject(name: AlertSoftButton, states: [imageSoftButtonState, textSoftButtonState], initialStateName: imageSoftButtonState.name) { (buttonPress, buttonEvent) in
- guard buttonPress != nil else { return }
- manager.fileManager.upload(artwork: SDLArtwork(image: UIImage(named: CarBWIconImageName)!, persistent: false, as: .PNG), completionHandler: { (success, artworkName, bytesAvailable, err) in
- let alert = AlertManager.alertWithMessageAndCloseButton("You pressed the button!", iconName: artworkName)
- manager.send(alert)
- })
+ private var softButtonAlert: SDLSoftButtonObject {
+ let imageAndTextState = SDLSoftButtonState(stateName: AlertSoftButtonImageAndTextState, text: AlertSoftButtonText, image: UIImage(named: AlertBWIconName)?.withRenderingMode(.alwaysTemplate))
+ let textState = SDLSoftButtonState(stateName: AlertSoftButtonTextState, text: AlertSoftButtonText, image: nil)
+ return SDLSoftButtonObject(name: AlertSoftButton, states: [imageAndTextState, textState], initialStateName: imageAndTextState.name) { [weak self] (buttonPress, buttonEvent) in
+ guard let self = self, buttonPress != nil else { return }
+
+ if (self.isAlertAllowed) {
+ AlertManager.sendAlert(imageName: CarBWIconImageName, textField1: AlertMessageText, sdlManager: self.sdlManager)
+ } else if (self.isSubtleAlertAllowed) {
+ AlertManager.sendSubtleAlert(imageName: CarBWIconImageName, textField1: AlertMessageText, sdlManager: self.sdlManager)
+ } else {
+ SDLLog.w("The module does not support the Alert request or the Subtle Alert request")
+ }
}
}
- /// Returns a soft button that toggles between two states: on and off. If images are currently visible, the button image toggles; if images aren't visible, the button text toggles.
- ///
- /// - Returns: A soft button
- func softButtonToggle() -> SDLSoftButtonObject {
- let imageOnState = SDLSoftButtonState(stateName: ToggleSoftButtonImageOnState, text: nil, image: UIImage(named: ToggleOnBWIconName)?.withRenderingMode(.alwaysTemplate))
- let imageOffState = SDLSoftButtonState(stateName: ToggleSoftButtonImageOffState, text: nil, image: UIImage(named: ToggleOffBWIconName)?.withRenderingMode(.alwaysTemplate))
- return SDLSoftButtonObject(name: ToggleSoftButton, states: [imageOnState, imageOffState], initialStateName: imageOnState.name) { [unowned self] (buttonPress, buttonEvent) in
- guard buttonPress != nil else { return }
- self.toggleEnabled = !self.toggleEnabled
+ /// Returns a soft button that shows a subtle alert when tapped. If the subtle alert is not supported, then a regular alert is shown.
+ private var softButtonSubtleAlert: SDLSoftButtonObject {
+ let imageAndTextState = SDLSoftButtonState(stateName: SubtleAlertSoftButtonImageAndTextState, text: SubtleAlertSoftButtonText, image: UIImage(named: BatteryFullBWIconName)?.withRenderingMode(.alwaysTemplate))
+ let textState = SDLSoftButtonState(stateName: SubtleAlertSoftButtonTextState, text: SubtleAlertSoftButtonText, image: nil)
+ return SDLSoftButtonObject(name: SubtleAlertSoftButton, states: [imageAndTextState, textState], initialStateName: imageAndTextState.name) { [weak self] (buttonPress, buttonEvent) in
+ guard let self = self, buttonPress != nil else { return }
+
+ if (self.isSubtleAlertAllowed) {
+ AlertManager.sendSubtleAlert(imageName: BatteryEmptyBWIconName, textField1: SubtleAlertHeaderText, textField2: SubtleAlertSubheaderText, sdlManager: self.sdlManager)
+ } else if (self.isAlertAllowed) {
+ AlertManager.sendAlert(imageName: BatteryEmptyBWIconName, textField1: SubtleAlertHeaderText, textField2: SubtleAlertSubheaderText, sdlManager: self.sdlManager)
+ } else {
+ SDLLog.w("The module does not support the Alert request or the Subtle Alert request")
+ }
}
}
- /// Returns a soft button that toggles the textfield visibility state for the SDL UI. The button's text toggles based on the current text visibility.
- ///
- /// - Returns: A soft button
- func softButtonTextVisible() -> SDLSoftButtonObject {
+ /// Returns a soft button that toggles the textfield visibility state.
+ private var softButtonTextVisible: SDLSoftButtonObject {
let textVisibleState = SDLSoftButtonState(stateName: TextVisibleSoftButtonTextOnState, text: TextVisibleSoftButtonTextOnText, artwork: nil)
let textNotVisibleState = SDLSoftButtonState(stateName: TextVisibleSoftButtonTextOffState, text: TextVisibleSoftButtonTextOffText, image: nil)
return SDLSoftButtonObject(name: TextVisibleSoftButton, states: [textVisibleState, textNotVisibleState], initialStateName: textVisibleState.name) { [unowned self] (buttonPress, buttonEvent) in
@@ -105,19 +107,26 @@ private extension ButtonManager {
}
}
- /// Returns a soft button that toggles the image visibility state for the SDL UI. The button's text toggles based on the current image visibility.
- ///
- /// - Returns: A soft button
- func softButtonImagesVisible() -> SDLSoftButtonObject {
+ /// Returns a soft button that toggles the image visibility state.
+ private var softButtonImagesVisible: SDLSoftButtonObject {
let imagesVisibleState = SDLSoftButtonState(stateName: ImagesVisibleSoftButtonImageOnState, text: ImagesVisibleSoftButtonImageOnText, image: nil)
let imagesNotVisibleState = SDLSoftButtonState(stateName: ImagesVisibleSoftButtonImageOffState, text: ImagesVisibleSoftButtonImageOffText, image: nil)
- return SDLSoftButtonObject(name: ImagesVisibleSoftButton, states: [imagesVisibleState, imagesNotVisibleState], initialStateName: imagesVisibleState.name) { [unowned self] (buttonPress, buttonEvent) in
- guard buttonPress != nil else { return }
+ return SDLSoftButtonObject(name: ImagesVisibleSoftButton, states: [imagesVisibleState, imagesNotVisibleState], initialStateName: imagesVisibleState.name) { [weak self] (buttonPress, buttonEvent) in
+ guard let self = self, let sdlManager = self.sdlManager, buttonPress != nil else { return }
+
self.imagesEnabled = !self.imagesEnabled
- // Update the button state
- let softButton = self.sdlManager.screenManager.softButtonObjectNamed(ImagesVisibleSoftButton)
- softButton?.transitionToNextState()
+ if let imagesVisibleSoftButton = sdlManager.screenManager.softButtonObjectNamed(ImagesVisibleSoftButton) {
+ imagesVisibleSoftButton.transitionToNextState()
+ }
+
+ if let alertSoftButton = sdlManager.screenManager.softButtonObjectNamed(AlertSoftButton) {
+ alertSoftButton.transitionToNextState()
+ }
+
+ if let subtleAlertSoftButton = sdlManager.screenManager.softButtonObjectNamed(SubtleAlertSoftButton) {
+ subtleAlertSoftButton.transitionToNextState()
+ }
}
}
}
diff --git a/Example Apps/Example Swift/MenuManager.swift b/Example Apps/Example Swift/MenuManager.swift
index cdf478149..96f013d01 100644
--- a/Example Apps/Example Swift/MenuManager.swift
+++ b/Example Apps/Example Swift/MenuManager.swift
@@ -98,7 +98,7 @@ private extension MenuManager {
}
return SDLMenuCell(title: ACRecordInCarMicrophoneAudioMenuName, icon: SDLArtwork(image: UIImage(named: SpeakBWIconImageName)!.withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), voiceCommands: [ACRecordInCarMicrophoneAudioMenuName], handler: { _ in
- manager.send(AlertManager.alertWithMessageAndCloseButton("Speech recognition feature only available on iOS 10+"))
+ AlertManager.sendAlert(textField1: "Speech recognition feature only available on iOS 10+", sdlManager: manager)
})
}
@@ -109,7 +109,7 @@ private extension MenuManager {
class func menuCellDialNumber(with manager: SDLManager) -> SDLMenuCell {
return SDLMenuCell(title: ACDialPhoneNumberMenuName, icon: SDLArtwork(image: UIImage(named: PhoneBWIconImageName)!.withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), voiceCommands: [ACDialPhoneNumberMenuName], handler: { _ in
guard RPCPermissionsManager.isDialNumberRPCAllowed(with: manager) else {
- manager.send(AlertManager.alertWithMessageAndCloseButton("This app does not have the required permissions to dial a number"))
+ AlertManager.sendAlert(textField1: AlertDialNumberPermissionsWarningText, sdlManager: manager)
return
}
@@ -133,7 +133,7 @@ private extension MenuManager {
let display = SDLSetDisplayLayout(predefinedLayout: .nonMedia)
manager.send(request: display) { (request, response, error) in
guard response?.success.boolValue == .some(true) else {
- manager.send(AlertManager.alertWithMessageAndCloseButton(errorMessage))
+ AlertManager.sendAlert(textField1: errorMessage, sdlManager: manager)
return
}
}
@@ -145,7 +145,7 @@ private extension MenuManager {
let display = SDLSetDisplayLayout(predefinedLayout: .graphicWithText)
manager.send(request: display) { (request, response, error) in
guard response?.success.boolValue == .some(true) else {
- manager.send(AlertManager.alertWithMessageAndCloseButton(errorMessage))
+ AlertManager.sendAlert(textField1: errorMessage, sdlManager: manager)
return
}
}
@@ -166,7 +166,7 @@ private extension MenuManager {
let message = "\(submenuTitle) selected!"
switch triggerSource {
case .menu:
- manager.send(AlertManager.alertWithMessageAndCloseButton(message))
+ AlertManager.sendAlert(textField1: message, sdlManager: manager)
case .voiceRecognition:
manager.send(SDLSpeak(tts: message))
default: break
@@ -184,11 +184,11 @@ private extension MenuManager {
guard let response = response else { return }
guard response.resultCode == .success else {
if response.resultCode == .timedOut {
- manager.send(AlertManager.alertWithMessageAndCloseButton("Slider timed out"))
+ AlertManager.sendAlert(textField1: AlertSliderTimedOutWarningText, sdlManager: manager)
} else if response.resultCode == .aborted {
- manager.send(AlertManager.alertWithMessageAndCloseButton("Slider cancelled"))
+ AlertManager.sendAlert(textField1: AlertSliderCancelledWarningText, sdlManager: manager)
} else {
- manager.send(AlertManager.alertWithMessageAndCloseButton("Slider could not be displayed"))
+ AlertManager.sendAlert(textField1: AlertSliderGeneralWarningText, sdlManager: manager)
}
return
}
@@ -203,11 +203,11 @@ private extension MenuManager {
guard let response = response else { return }
guard response.resultCode == .success else {
if response.resultCode == .timedOut {
- manager.send(AlertManager.alertWithMessageAndCloseButton("Scrollable Message timed out"))
+ AlertManager.sendAlert(textField1: AlertScrollableMessageTimedOutWarningText, sdlManager: manager)
} else if response.resultCode == .aborted {
- manager.send(AlertManager.alertWithMessageAndCloseButton("Scrollable Message cancelled"))
+ AlertManager.sendAlert(textField1: AlertScrollableMessageCancelledWarningText, sdlManager: manager)
} else {
- manager.send(AlertManager.alertWithMessageAndCloseButton("Scrollable Message could not be displayed"))
+ AlertManager.sendAlert(textField1: AlertScrollableMessageGeneralWarningText, sdlManager: manager)
}
return
}
@@ -225,7 +225,7 @@ private extension MenuManager {
/// - Returns: A SDLVoiceCommand object
class func voiceCommandStart(with manager: SDLManager) -> SDLVoiceCommand {
return SDLVoiceCommand(voiceCommands: [VCStart], handler: {
- manager.send(AlertManager.alertWithMessageAndCloseButton("\(VCStart) voice command selected!"))
+ AlertManager.sendAlert(textField1: "\(VCStart) voice command selected!", sdlManager: manager)
})
}
@@ -235,7 +235,7 @@ private extension MenuManager {
/// - Returns: A SDLVoiceCommand object
class func voiceCommandStop(with manager: SDLManager) -> SDLVoiceCommand {
return SDLVoiceCommand(voiceCommands: [VCStop], handler: {
- manager.send(AlertManager.alertWithMessageAndCloseButton("\(VCStop) voice command selected!"))
+ AlertManager.sendAlert(textField1: "\(VCStop) voice command selected!", sdlManager: manager)
})
}
}
diff --git a/Example Apps/Example Swift/ProxyManager.swift b/Example Apps/Example Swift/ProxyManager.swift
index fdad60360..ab6f656d9 100644
--- a/Example Apps/Example Swift/ProxyManager.swift
+++ b/Example Apps/Example Swift/ProxyManager.swift
@@ -255,7 +255,7 @@ private extension ProxyManager {
sdlManager.send(setDisplayLayout)
updateScreen()
- sdlManager.screenManager.softButtonObjects = buttonManager.allScreenSoftButtons(with: sdlManager)
+ sdlManager.screenManager.softButtonObjects = buttonManager.allScreenSoftButtons()
}
/// Update the UI's textfields, images and soft buttons
diff --git a/Example Apps/Example Swift/VehicleDataManager.swift b/Example Apps/Example Swift/VehicleDataManager.swift
index c0f6e59dc..3c83f2ff9 100644
--- a/Example Apps/Example Swift/VehicleDataManager.swift
+++ b/Example Apps/Example Swift/VehicleDataManager.swift
@@ -144,9 +144,7 @@ extension VehicleDataManager {
if triggerSource == .menu {
let title = !alertTitle.isEmpty ? alertTitle : "No Vehicle Data Available"
let detailMessage = !alertMessage.isEmpty ? alertMessage : nil
- let alert = AlertManager.alertWithMessageAndCloseButton(title,
- textField2: detailMessage)
- manager.send(alert)
+ AlertManager.sendAlert(textField1: title, textField2: detailMessage, sdlManager: manager)
} else {
let spokenAlert = !alertMessage.isEmpty ? alertMessage : alertTitle
manager.send(SDLSpeak(tts: spokenAlert))
@@ -233,8 +231,7 @@ extension VehicleDataManager {
SDLLog.d("Checking if app has permission to access vehicle data...")
guard manager.permissionManager.isRPCNameAllowed(SDLRPCFunctionName.getVehicleData) else {
- let alert = AlertManager.alertWithMessageAndCloseButton("This app does not have the required permissions to access vehicle data")
- manager.send(request: alert)
+ AlertManager.sendAlert(textField1: AlertVehicleDataPermissionsWarningText, sdlManager: manager)
return false
}
@@ -252,8 +249,7 @@ extension VehicleDataManager {
SDLLog.d("Checking if Core returned vehicle data")
guard response != nil, error == nil else {
- let alert = AlertManager.alertWithMessageAndCloseButton("Something went wrong while getting vehicle data")
- manager.send(request: alert)
+ AlertManager.sendAlert(textField1: AlertVehicleDataGeneralWarningText, sdlManager: manager)
return false
}
@@ -272,14 +268,14 @@ extension VehicleDataManager {
SDLLog.d("Checking phone call capability")
manager.systemCapabilityManager.updateCapabilityType(.phoneCall, completionHandler: { (error, systemCapabilityManager) in
guard let phoneCapability = systemCapabilityManager.phoneCapability else {
- manager.send(AlertManager.alertWithMessageAndCloseButton("The head unit does not support the phone call capability"))
+ AlertManager.sendAlert(textField1: AlertDialNumberPermissionsWarningText, sdlManager: manager)
return
}
if phoneCapability.dialNumberEnabled?.boolValue ?? false {
SDLLog.d("Dialing phone number \(phoneNumber)...")
dialPhoneNumber(phoneNumber, manager: manager)
} else {
- manager.send(AlertManager.alertWithMessageAndCloseButton("A phone call can not be made"))
+ AlertManager.sendAlert(textField1: AlertDialNumberUnavailableWarningText, sdlManager: manager)
}
})
}
diff --git a/Example Apps/Shared/AppConstants.h b/Example Apps/Shared/AppConstants.h
index 5fb4b25b0..c022f5570 100644
--- a/Example Apps/Shared/AppConstants.h
+++ b/Example Apps/Shared/AppConstants.h
@@ -22,16 +22,13 @@ extern NSString * const SmartDeviceLinkText;
extern NSString * const ExampleAppText;
#pragma mark - SDL Soft Buttons
-extern NSString * const ToggleSoftButton;
-extern NSString * const ToggleSoftButtonImageOnState;
-extern NSString * const ToggleSoftButtonImageOffState;
-extern NSString * const ToggleSoftButtonTextOnState;
-extern NSString * const ToggleSoftButtonTextOffState;
-extern NSString * const ToggleSoftButtonTextTextOnText;
-extern NSString * const ToggleSoftButtonTextTextOffText;
+extern NSString * const SubtleAlertSoftButton;
+extern NSString * const SubtleAlertSoftButtonImageAndTextState;
+extern NSString * const SubtleAlertSoftButtonTextState;
+extern NSString * const SubtleAlertSoftButtonText;
extern NSString * const AlertSoftButton;
-extern NSString * const AlertSoftButtonImageState;
+extern NSString * const AlertSoftButtonImageAndTextState;
extern NSString * const AlertSoftButtonTextState;
extern NSString * const AlertSoftButtonText;
@@ -48,7 +45,21 @@ extern NSString * const ImagesVisibleSoftButtonImageOnText;
extern NSString * const ImagesVisibleSoftButtonImageOffText;
#pragma mark - Alert
+extern NSString * const AlertMessageText;
extern NSString * const AlertOKButtonText;
+extern NSString * const SubtleAlertHeaderText;
+extern NSString * const SubtleAlertSubheaderText;
+extern NSString * const AlertDialNumberPermissionsWarningText;
+extern NSString * const AlertDialNumberUnavailableWarningText;
+extern NSString * const AlertSliderTimedOutWarningText;
+extern NSString * const AlertSliderCancelledWarningText;
+extern NSString * const AlertSliderGeneralWarningText;
+extern NSString * const AlertScrollableMessageTimedOutWarningText;
+extern NSString * const AlertScrollableMessageCancelledWarningText;
+extern NSString * const AlertScrollableMessageGeneralWarningText;
+extern NSString * const AlertVehicleDataPermissionsWarningText;
+extern NSString * const AlertVehicleDataGeneralWarningText;
+extern NSString * const AlertSpeechPermissionsWarningText;
#pragma mark - SDL Text-To-Speech
extern NSString * const TTSGoodJob;
@@ -123,8 +134,8 @@ extern NSString * const MenuBWIconImageName;
extern NSString * const MicrophoneBWIconImageName;
extern NSString * const PhoneBWIconImageName;
extern NSString * const SpeakBWIconImageName;
-extern NSString * const ToggleOffBWIconName;
-extern NSString * const ToggleOnBWIconName;
+extern NSString * const BatteryEmptyBWIconName;
+extern NSString * const BatteryFullBWIconName;
#pragma mark - SDL App Name in Different Languages
extern NSString * const ExampleAppNameSpanish;
diff --git a/Example Apps/Shared/AppConstants.m b/Example Apps/Shared/AppConstants.m
index ffe4762d1..207d0bcda 100644
--- a/Example Apps/Shared/AppConstants.m
+++ b/Example Apps/Shared/AppConstants.m
@@ -19,18 +19,15 @@ NSString * const SmartDeviceLinkText = @"SmartDeviceLink (SDL)";
NSString * const ExampleAppText = @"Example App";
#pragma mark - SDL Soft Buttons
-NSString * const ToggleSoftButton = @"ToggleSoftButton";
-NSString * const ToggleSoftButtonImageOnState = @"ToggleSoftButtonImageOnState";
-NSString * const ToggleSoftButtonImageOffState = @"ToggleSoftButtonImageOffState";
-NSString * const ToggleSoftButtonTextOnState = @"ToggleSoftButtonTextOnState";
-NSString * const ToggleSoftButtonTextOffState = @"ToggleSoftButtonTextOffState";
-NSString * const ToggleSoftButtonTextTextOnText = @"➖";
-NSString * const ToggleSoftButtonTextTextOffText = @"➕";
+NSString * const SubtleAlertSoftButton = @"SubtleAlertSoftButton";
+NSString * const SubtleAlertSoftButtonImageAndTextState = @"SubtleAlertSoftButtonImageAndTextState";
+NSString * const SubtleAlertSoftButtonTextState = @"SubtleAlertSoftButtonTextState";
+NSString * const SubtleAlertSoftButtonText = @"Check Battery";
NSString * const AlertSoftButton = @"AlertSoftButton";
-NSString * const AlertSoftButtonImageState = @"AlertSoftButtonImageState";
+NSString * const AlertSoftButtonImageAndTextState = @"AlertSoftButtonImageAndTextState";
NSString * const AlertSoftButtonTextState = @"AlertSoftButtonTextState";
-NSString * const AlertSoftButtonText = @"Tap Me";
+NSString * const AlertSoftButtonText = @"Show Alert";
NSString * const TextVisibleSoftButton = @"TextVisibleSoftButton";
NSString * const TextVisibleSoftButtonTextOnState = @"TextVisibleSoftButtonTextOnState";
@@ -45,7 +42,21 @@ NSString * const ImagesVisibleSoftButtonImageOnText = @"➖Icons";
NSString * const ImagesVisibleSoftButtonImageOffText = @"➕Icons";
#pragma mark - Alert
+NSString * const AlertMessageText = @"You pressed the button!";
NSString * const AlertOKButtonText = @"OK";
+NSString * const SubtleAlertHeaderText = @"Battery Level";
+NSString * const SubtleAlertSubheaderText = @"Almost empty";
+NSString * const AlertDialNumberPermissionsWarningText = @"This app does not have the required permissions to dial a number";
+NSString * const AlertDialNumberUnavailableWarningText = @"The dial number feature is unavailable for this head unit";
+NSString * const AlertSliderTimedOutWarningText = @"Slider timed out";
+NSString * const AlertSliderCancelledWarningText = @"Slider cancelled";
+NSString * const AlertSliderGeneralWarningText = @"Slider could not be displayed";
+NSString * const AlertScrollableMessageTimedOutWarningText = @"Scrollable Message timed out";
+NSString * const AlertScrollableMessageCancelledWarningText = @"Scrollable Message cancelled";
+NSString * const AlertScrollableMessageGeneralWarningText = @"Scrollable Message could not be displayed";
+NSString * const AlertVehicleDataPermissionsWarningText = @"This app does not have the required permissions to access vehicle data";
+NSString * const AlertVehicleDataGeneralWarningText = @"Something went wrong while getting vehicle data";
+NSString * const AlertSpeechPermissionsWarningText = @"You must give this app permission to access Speech Recognition";
#pragma mark - SDL Text-To-Speech
NSString * const TTSGoodJob = @"Good Job";
@@ -120,8 +131,8 @@ NSString * const MenuBWIconImageName = @"choice_set";
NSString * const MicrophoneBWIconImageName = @"microphone";
NSString * const PhoneBWIconImageName = @"phone";
NSString * const SpeakBWIconImageName = @"speak";
-NSString * const ToggleOffBWIconName = @"toggle_off";
-NSString * const ToggleOnBWIconName = @"toggle_on";
+NSString * const BatteryEmptyBWIconName = @"toggle_off";
+NSString * const BatteryFullBWIconName = @"toggle_on";
#pragma mark - SDL App Name in Different Languages
NSString * const ExampleAppNameSpanish = @"SDL Aplicación de ejemplo";
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index df55022a3..b97011254 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -252,6 +252,7 @@ s.public_header_files = [
'SmartDeviceLink/SDLOnLockScreenStatus.h',
'SmartDeviceLink/SDLOnPermissionsChange.h',
'SmartDeviceLink/SDLOnRCStatus.h',
+'SmartDeviceLink/SDLOnSubtleAlertPressed.h',
'SmartDeviceLink/SDLOnSyncPData.h',
'SmartDeviceLink/SDLOnSystemCapabilityUpdated.h',
'SmartDeviceLink/SDLOnSystemRequest.h',
@@ -380,6 +381,8 @@ s.public_header_files = [
'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h',
'SmartDeviceLink/SDLSubscribeWaypoints.h',
'SmartDeviceLink/SDLSubscribeWaypointsResponse.h',
+'SmartDeviceLink/SDLSubtleAlert.h',
+'SmartDeviceLink/SDLSubtleAlertResponse.h',
'SmartDeviceLink/SDLSupportedSeat.h',
'SmartDeviceLink/SDLSyncMsgVersion.h',
'SmartDeviceLink/SDLMsgVersion.h',
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index d6c201998..40096aaf7 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -1434,6 +1434,15 @@
888DBAF022D528DE002A0AE2 /* SDLCloseApplicationResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 888DBAEE22D528DE002A0AE2 /* SDLCloseApplicationResponse.m */; };
888F86FE221DEE200052FE4C /* SDLAsynchronousRPCOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FD221DEE1F0052FE4C /* SDLAsynchronousRPCOperation.m */; };
888F8700221DF4880052FE4C /* SDLAsynchronousRPCOperationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FF221DF4880052FE4C /* SDLAsynchronousRPCOperationSpec.m */; };
+ 889D0B8F24D052FE008AD494 /* SDLSubtleAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 889D0B8D24D052FD008AD494 /* SDLSubtleAlert.m */; };
+ 889D0B9024D052FE008AD494 /* SDLSubtleAlert.h in Headers */ = {isa = PBXBuildFile; fileRef = 889D0B8E24D052FD008AD494 /* SDLSubtleAlert.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 889D0B9324D05A0E008AD494 /* SDLSubtleAlertResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 889D0B9124D05A0E008AD494 /* SDLSubtleAlertResponse.m */; };
+ 889D0B9424D05A0E008AD494 /* SDLSubtleAlertResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 889D0B9224D05A0E008AD494 /* SDLSubtleAlertResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 889D0B9624D065EE008AD494 /* SDLSubtleAlertResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 889D0B9524D065EE008AD494 /* SDLSubtleAlertResponseSpec.m */; };
+ 889D0B9824D06E52008AD494 /* SDLSubtleAlertSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 889D0B9724D06E52008AD494 /* SDLSubtleAlertSpec.m */; };
+ 889D0B9B24D07DCB008AD494 /* SDLOnSubtleAlertPressed.m in Sources */ = {isa = PBXBuildFile; fileRef = 889D0B9924D07DCB008AD494 /* SDLOnSubtleAlertPressed.m */; };
+ 889D0B9C24D07DCB008AD494 /* SDLOnSubtleAlertPressed.h in Headers */ = {isa = PBXBuildFile; fileRef = 889D0B9A24D07DCB008AD494 /* SDLOnSubtleAlertPressed.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 889D0B9E24D07FF8008AD494 /* SDLOnSubtleAlertPressedSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 889D0B9D24D07FF8008AD494 /* SDLOnSubtleAlertPressedSpec.m */; };
889E7BAF249CEE07002E4BE1 /* SubscribeButtonManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 889E7BAD249CEDCF002E4BE1 /* SubscribeButtonManager.swift */; };
889E7BB2249D0877002E4BE1 /* SubscribeButtonManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 889E7BB1249D0877002E4BE1 /* SubscribeButtonManager.m */; };
88A098AE2476F0C200A50005 /* SDLSubscribeButtonManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 88A098AC2476F0C200A50005 /* SDLSubscribeButtonManager.h */; };
@@ -3228,6 +3237,15 @@
888DBAEE22D528DE002A0AE2 /* SDLCloseApplicationResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLCloseApplicationResponse.m; sourceTree = "<group>"; };
888F86FD221DEE1F0052FE4C /* SDLAsynchronousRPCOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLAsynchronousRPCOperation.m; sourceTree = "<group>"; };
888F86FF221DF4880052FE4C /* SDLAsynchronousRPCOperationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLAsynchronousRPCOperationSpec.m; sourceTree = "<group>"; };
+ 889D0B8D24D052FD008AD494 /* SDLSubtleAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSubtleAlert.m; sourceTree = "<group>"; };
+ 889D0B8E24D052FD008AD494 /* SDLSubtleAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLSubtleAlert.h; sourceTree = "<group>"; };
+ 889D0B9124D05A0E008AD494 /* SDLSubtleAlertResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSubtleAlertResponse.m; sourceTree = "<group>"; };
+ 889D0B9224D05A0E008AD494 /* SDLSubtleAlertResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLSubtleAlertResponse.h; sourceTree = "<group>"; };
+ 889D0B9524D065EE008AD494 /* SDLSubtleAlertResponseSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLSubtleAlertResponseSpec.m; sourceTree = "<group>"; };
+ 889D0B9724D06E52008AD494 /* SDLSubtleAlertSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLSubtleAlertSpec.m; sourceTree = "<group>"; };
+ 889D0B9924D07DCB008AD494 /* SDLOnSubtleAlertPressed.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLOnSubtleAlertPressed.m; sourceTree = "<group>"; };
+ 889D0B9A24D07DCB008AD494 /* SDLOnSubtleAlertPressed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLOnSubtleAlertPressed.h; sourceTree = "<group>"; };
+ 889D0B9D24D07FF8008AD494 /* SDLOnSubtleAlertPressedSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLOnSubtleAlertPressedSpec.m; sourceTree = "<group>"; };
889E7BAD249CEDCF002E4BE1 /* SubscribeButtonManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscribeButtonManager.swift; sourceTree = "<group>"; };
889E7BB0249D0877002E4BE1 /* SubscribeButtonManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SubscribeButtonManager.h; sourceTree = "<group>"; };
889E7BB1249D0877002E4BE1 /* SubscribeButtonManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SubscribeButtonManager.m; sourceTree = "<group>"; };
@@ -3746,6 +3764,7 @@
162E82341A9BDE8A00906325 /* SDLOnLockScreenStatusSpec.m */,
162E82351A9BDE8A00906325 /* SDLOnPermissionsChangeSpec.m */,
1EAA470D2032BF1D000FE74B /* SDLOnRCStatusSpec.m */,
+ 889D0B9D24D07FF8008AD494 /* SDLOnSubtleAlertPressedSpec.m */,
162E82361A9BDE8A00906325 /* SDLOnSyncPDataSpec.m */,
88A5E7F3220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m */,
162E82371A9BDE8A00906325 /* SDLOnSystemRequestSpec.m */,
@@ -3819,6 +3838,7 @@
162E825D1A9BDE8A00906325 /* SDLSubscribeButtonSpec.m */,
162E825E1A9BDE8A00906325 /* SDLSubscribeVehicleDataSpec.m */,
DA9F7EA31DCC05EE00ACAE48 /* SDLSubscribeWaypointsSpec.m */,
+ 889D0B9724D06E52008AD494 /* SDLSubtleAlertSpec.m */,
162E825F1A9BDE8A00906325 /* SDLSyncPDataSpec.m */,
162E82601A9BDE8A00906325 /* SDLSystemRequestSpec.m */,
162E82611A9BDE8A00906325 /* SDLUnregisterAppInterfaceSpec.m */,
@@ -3893,6 +3913,7 @@
162E82861A9BDE8A00906325 /* SDLSubscribeButtonResponseSpec.m */,
162E82871A9BDE8A00906325 /* SDLSubscribeVehicleDataResponseSpec.m */,
DA9F7EA91DCC061A00ACAE48 /* SDLSubscribeWaypointsResponseSpec.m */,
+ 889D0B9524D065EE008AD494 /* SDLSubtleAlertResponseSpec.m */,
162E82881A9BDE8A00906325 /* SDLSyncPDataResponseSpec.m */,
162E82891A9BDE8A00906325 /* SDLSystemRequestResponseSpec.m */,
162E828A1A9BDE8A00906325 /* SDLUnregisterAppInterfaceResponseSpec.m */,
@@ -4710,6 +4731,8 @@
5D61FBC51A84238B00846EE7 /* SDLSubscribeVehicleData.m */,
DA9F7E851DCC049900ACAE48 /* SDLSubscribeWayPoints.h */,
DA9F7E861DCC049900ACAE48 /* SDLSubscribeWayPoints.m */,
+ 889D0B8E24D052FD008AD494 /* SDLSubtleAlert.h */,
+ 889D0B8D24D052FD008AD494 /* SDLSubtleAlert.m */,
5D61FBCA1A84238B00846EE7 /* SDLSyncPData.h */,
5D61FBCB1A84238B00846EE7 /* SDLSyncPData.m */,
5D61FBD21A84238B00846EE7 /* SDLSystemRequest.h */,
@@ -4845,6 +4868,8 @@
5D61FBC71A84238B00846EE7 /* SDLSubscribeVehicleDataResponse.m */,
DA9F7E891DCC04B000ACAE48 /* SDLSubscribeWayPointsResponse.h */,
DA9F7E8A1DCC04B000ACAE48 /* SDLSubscribeWayPointsResponse.m */,
+ 889D0B9224D05A0E008AD494 /* SDLSubtleAlertResponse.h */,
+ 889D0B9124D05A0E008AD494 /* SDLSubtleAlertResponse.m */,
5D61FBCC1A84238B00846EE7 /* SDLSyncPDataResponse.h */,
5D61FBCD1A84238B00846EE7 /* SDLSyncPDataResponse.m */,
5D61FBD41A84238B00846EE7 /* SDLSystemRequestResponse.h */,
@@ -5387,6 +5412,8 @@
5D61FB2B1A84238B00846EE7 /* SDLOnPermissionsChange.m */,
1EAA47092032BAE5000FE74B /* SDLOnRCStatus.h */,
1EAA470A2032BAE5000FE74B /* SDLOnRCStatus.m */,
+ 889D0B9A24D07DCB008AD494 /* SDLOnSubtleAlertPressed.h */,
+ 889D0B9924D07DCB008AD494 /* SDLOnSubtleAlertPressed.m */,
5D61FB2C1A84238B00846EE7 /* SDLOnSyncPData.h */,
5D61FB2D1A84238B00846EE7 /* SDLOnSyncPData.m */,
884AF94D220B488900E22928 /* SDLOnSystemCapabilityUpdated.h */,
@@ -6898,6 +6925,7 @@
5D61FCB51A84238C00846EE7 /* SDLGetVehicleData.h in Headers */,
5D61FDEB1A84238C00846EE7 /* SDLUnsubscribeVehicleData.h in Headers */,
5DA3F3541BC448060026F2D0 /* NSMapTable+Subscripting.h in Headers */,
+ 889D0B9424D05A0E008AD494 /* SDLSubtleAlertResponse.h in Headers */,
5D61FC591A84238C00846EE7 /* SDLCarModeStatus.h in Headers */,
5D1665C41CF8CA2700CC4CA1 /* SDLListFilesOperation.h in Headers */,
5D61FC2B1A84238C00846EE7 /* SDLTransportType.h in Headers */,
@@ -7066,6 +7094,7 @@
5D61FD571A84238C00846EE7 /* SDLPutFileResponse.h in Headers */,
5D61FD411A84238C00846EE7 /* SDLPRNDL.h in Headers */,
5D61FDE51A84238C00846EE7 /* SDLUnregisterAppInterfaceResponse.h in Headers */,
+ 889D0B9C24D07DCB008AD494 /* SDLOnSubtleAlertPressed.h in Headers */,
5D61FCF81A84238C00846EE7 /* SDLMenuParams.h in Headers */,
5D61FD651A84238C00846EE7 /* SDLResetGlobalPropertiesResponse.h in Headers */,
DA9F7E671DCBFAD400ACAE48 /* SDLOasisAddress.h in Headers */,
@@ -7076,6 +7105,7 @@
5D2F58081D0717D5001085CE /* SDLManagerDelegate.h in Headers */,
5D61FC881A84238C00846EE7 /* SDLDiagnosticMessage.h in Headers */,
5D0A738A203F24320001595D /* SDLSoftButtonObject.h in Headers */,
+ 889D0B9024D052FE008AD494 /* SDLSubtleAlert.h in Headers */,
5D61FDB31A84238C00846EE7 /* SDLSubscribeVehicleDataResponse.h in Headers */,
5D92935A20B33D4F00FCC775 /* SDLChoiceCell.h in Headers */,
B38D8E61249FE28500B977D0 /* SDLCapacityUnit.h in Headers */,
@@ -7704,6 +7734,7 @@
DA9F7E741DCC004C00ACAE48 /* SDLGetWayPointsResponse.m in Sources */,
5D61FD4D1A84238C00846EE7 /* SDLProtocolMessageDisassembler.m in Sources */,
5D61FD4B1A84238C00846EE7 /* SDLProtocolMessageAssembler.m in Sources */,
+ 889D0B9B24D07DCB008AD494 /* SDLOnSubtleAlertPressed.m in Sources */,
5D61FCC41A84238C00846EE7 /* SDLHMIPermissions.m in Sources */,
5D61FE141A84238C00846EE7 /* SDLWiperStatus.m in Sources */,
5D61FC8B1A84238C00846EE7 /* SDLDiagnosticMessageResponse.m in Sources */,
@@ -7730,6 +7761,7 @@
5D8204271BCEA8A600D0A41B /* SDLPermissionManager.m in Sources */,
5D61FDB21A84238C00846EE7 /* SDLSubscribeVehicleData.m in Sources */,
5D61FC991A84238C00846EE7 /* SDLECallInfo.m in Sources */,
+ 889D0B8F24D052FE008AD494 /* SDLSubtleAlert.m in Sources */,
5D61FD601A84238C00846EE7 /* SDLRegisterAppInterfaceResponse.m in Sources */,
106982AB24AA3B4700B1F649 /* SDLRPCPermissionStatus.m in Sources */,
5DB996581F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.m in Sources */,
@@ -7968,6 +8000,7 @@
5DD67CBD1E661C84009CD394 /* SDLLogTargetOSLog.m in Sources */,
DA9F7E641DCBFAC800ACAE48 /* SDLDateTime.m in Sources */,
5D61FD581A84238C00846EE7 /* SDLPutFileResponse.m in Sources */,
+ 889D0B9324D05A0E008AD494 /* SDLSubtleAlertResponse.m in Sources */,
5D61FCB21A84238C00846EE7 /* SDLGetDTCs.m in Sources */,
8881AFB92225E5EE00EA870B /* SDLGetCloudAppProperties.m in Sources */,
5D61FD441A84238C00846EE7 /* SDLProtocol.m in Sources */,
@@ -8367,6 +8400,7 @@
162E83761A9BDE8B00906325 /* SDLChoiceSpec.m in Sources */,
162E83571A9BDE8B00906325 /* SDLGetDTCsResponseSpec.m in Sources */,
5D4346471E6F0BDA00B639C6 /* SDLLogFileModuleSpec.m in Sources */,
+ 889D0B9824D06E52008AD494 /* SDLSubtleAlertSpec.m in Sources */,
88A1CF1E21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m in Sources */,
1EE8C4581F387ABD00FDC2CF /* SDLButtonPressResponseSpec.m in Sources */,
884554AF2224554300BAFB6C /* SDLNavigationServiceManifestSpec.m in Sources */,
@@ -8388,6 +8422,7 @@
5D60DF26202B7A97001EDA01 /* SDLSequentialRPCRequestOperationSpec.m in Sources */,
162E832C1A9BDE8B00906325 /* SDLDiagnosticMessageSpec.m in Sources */,
162E83381A9BDE8B00906325 /* SDLScrollableMessageSpec.m in Sources */,
+ 889D0B9624D065EE008AD494 /* SDLSubtleAlertResponseSpec.m in Sources */,
162E82E81A9BDE8B00906325 /* SDLKeyboardLayoutSpec.m in Sources */,
5D64FE6F20DA9E4300792F9F /* SDLStreamingVideoLifecycleManagerSpec.m in Sources */,
DA9F7EA41DCC05EE00ACAE48 /* SDLSubscribeWaypointsSpec.m in Sources */,
@@ -8510,6 +8545,7 @@
5DC978261B7A38640012C2F1 /* SDLGlobalsSpec.m in Sources */,
162E82FF1A9BDE8B00906325 /* SDLTextAlignmentSpec.m in Sources */,
000DD57222EF063F005AB7A7 /* SDLGetInteriorVehicleDataConsentResponseSpec.m in Sources */,
+ 889D0B9E24D07FF8008AD494 /* SDLOnSubtleAlertPressedSpec.m in Sources */,
162E831F1A9BDE8B00906325 /* SDLOnTouchEventSpec.m in Sources */,
162E83921A9BDE8B00906325 /* SDLTouchEventCapabilitiesSpec.m in Sources */,
162E837F1A9BDE8B00906325 /* SDLHeadLampStatusSpec.m in Sources */,
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index 9b31599f3..d2cbc3524 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -256,6 +256,7 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLOnLockScreenStatus.h',
'SmartDeviceLink/SDLOnPermissionsChange.h',
'SmartDeviceLink/SDLOnRCStatus.h',
+'SmartDeviceLink/SDLOnSubtleAlertPressed.h',
'SmartDeviceLink/SDLOnSyncPData.h',
'SmartDeviceLink/SDLOnSystemCapabilityUpdated.h',
'SmartDeviceLink/SDLOnSystemRequest.h',
@@ -384,6 +385,8 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h',
'SmartDeviceLink/SDLSubscribeWaypoints.h',
'SmartDeviceLink/SDLSubscribeWaypointsResponse.h',
+'SmartDeviceLink/SDLSubtleAlert.h',
+'SmartDeviceLink/SDLSubtleAlertResponse.h',
'SmartDeviceLink/SDLSupportedSeat.h',
'SmartDeviceLink/SDLSyncMsgVersion.h',
'SmartDeviceLink/SDLMsgVersion.h',
diff --git a/SmartDeviceLink/SDLCancelInteraction.h b/SmartDeviceLink/SDLCancelInteraction.h
index 20b097699..289e85443 100644
--- a/SmartDeviceLink/SDLCancelInteraction.h
+++ b/SmartDeviceLink/SDLCancelInteraction.h
@@ -1,10 +1,34 @@
-//
-// SDLCancelInteraction.h
-// SmartDeviceLink
-//
-// Created by Nicole on 7/12/19.
-// Copyright © 2019 smartdevicelink. All rights reserved.
-//
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#import "SDLRPCRequest.h"
@@ -67,6 +91,14 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithPerformInteractionCancelID:(UInt32)cancelID;
/**
+ Convenience init for dismissing a subtle alert.
+
+ @param cancelID The ID of the specific subtle alert to dismiss
+ @return A SDLCancelInteraction object
+ */
+- (instancetype)initWithSubtleAlertCancelID:(UInt32)cancelID;
+
+/**
Convenience init for dismissing the currently presented alert.
@return A SDLCancelInteraction object
@@ -95,6 +127,13 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)performInteraction NS_SWIFT_NAME(performInteraction());
/**
+ Convenience init for dismissing the currently presented subtle alert.
+
+ @return A SDLCancelInteraction object
+ */
++ (instancetype)subtleAlert;
+
+/**
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
@@ -104,7 +143,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
The ID of the type of interaction to dismiss.
- Only values 10 (PerformInteractionID), 12 (AlertID), 25 (ScrollableMessageID), and 26 (SliderID) are permitted.
+ The ID of the type of interaction the developer wants to dismiss. Only values 10, (PerformInteractionID), 12 (AlertID), 25 (ScrollableMessageID), 26 (SliderID), and 64 (SubtleAlertID) are permitted.
Integer, Required
*/
diff --git a/SmartDeviceLink/SDLCancelInteraction.m b/SmartDeviceLink/SDLCancelInteraction.m
index 40de4fbef..bd591dc28 100644
--- a/SmartDeviceLink/SDLCancelInteraction.m
+++ b/SmartDeviceLink/SDLCancelInteraction.m
@@ -1,10 +1,34 @@
-//
-// SDLCancelInteraction.m
-// SmartDeviceLink
-//
-// Created by Nicole on 7/12/19.
-// Copyright © 2019 smartdevicelink. All rights reserved.
-//
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#import "SDLCancelInteraction.h"
@@ -65,6 +89,10 @@ NS_ASSUME_NONNULL_BEGIN
return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction].unsignedIntValue cancelID:cancelID];
}
+- (instancetype)initWithSubtleAlertCancelID:(UInt32)cancelID {
+ return [self initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSubtleAlert].unsignedIntValue cancelID:cancelID];
+}
+
+ (instancetype)alert {
return [[self alloc] initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameAlert].unsignedIntValue];
}
@@ -81,6 +109,10 @@ NS_ASSUME_NONNULL_BEGIN
return [[self alloc] initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction].unsignedIntValue];
}
++ (instancetype)subtleAlert {
+ return [[self alloc] initWithFunctionID:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSubtleAlert].unsignedIntValue];
+}
+
- (void)setCancelID:(nullable NSNumber<SDLInt> *)cancelID {
[self.parameters sdl_setObject:cancelID forName:SDLRPCParameterNameCancelID];
}
diff --git a/SmartDeviceLink/SDLFunctionID.m b/SmartDeviceLink/SDLFunctionID.m
index 705981e4c..aa649a40a 100644
--- a/SmartDeviceLink/SDLFunctionID.m
+++ b/SmartDeviceLink/SDLFunctionID.m
@@ -96,6 +96,7 @@ NS_ASSUME_NONNULL_BEGIN
@61: SDLRPCFunctionNameDeleteWindow,
@62: SDLRPCFunctionNameGetInteriorVehicleDataConsent,
@63: SDLRPCFunctionNameReleaseInteriorVehicleDataModule,
+ @64: SDLRPCFunctionNameSubtleAlert,
@32768: SDLRPCFunctionNameOnHMIStatus,
@32769: SDLRPCFunctionNameOnAppInterfaceUnregistered,
@32770: SDLRPCFunctionNameOnButtonEvent,
@@ -116,6 +117,7 @@ NS_ASSUME_NONNULL_BEGIN
@32785: SDLRPCFunctionNameOnRCStatus,
@32786: SDLRPCFunctionNameOnAppServiceData,
@32787: SDLRPCFunctionNameOnSystemCapabilityUpdated,
+ @32788: SDLRPCFunctionNameOnSubtleAlertPressed,
@32789: SDLRPCFunctionNameOnUpdateFile,
@32790: SDLRPCFunctionNameOnUpdateSubMenu,
#pragma clang diagnostic push
diff --git a/SmartDeviceLink/SDLImageFieldName.h b/SmartDeviceLink/SDLImageFieldName.h
index 44ddcbe27..4b54e4dbd 100644
--- a/SmartDeviceLink/SDLImageFieldName.h
+++ b/SmartDeviceLink/SDLImageFieldName.h
@@ -34,7 +34,7 @@
#import "SDLEnum.h"
/**
- The name that identifies the filed. Used in DisplayCapabilities.
+ The name that identifies the field. Used in DisplayCapabilities.
@since SmartDeviceLink 3.0
*/
@@ -118,3 +118,9 @@ extern SDLImageFieldName const SDLImageFieldNameLocationImage;
* @since SDL 7.0.0
*/
extern SDLImageFieldName const SDLImageFieldNameSubMenuIcon;
+
+ * The image of the subtle alert; applies to `SubtleAlert` `alertImage`
+ *
+ * @since SDL 7.0
+ */
+extern SDLImageFieldName const SDLImageFieldNameSubtleAlertIcon;
diff --git a/SmartDeviceLink/SDLImageFieldName.m b/SmartDeviceLink/SDLImageFieldName.m
index 0462e7f89..dd195ce82 100644
--- a/SmartDeviceLink/SDLImageFieldName.m
+++ b/SmartDeviceLink/SDLImageFieldName.m
@@ -48,3 +48,4 @@ SDLImageFieldName const SDLImageFieldNameShowConstantTBTIcon = @"showConstantTBT
SDLImageFieldName const SDLImageFieldNameShowConstantTBTNextTurnIcon = @"showConstantTBTNextTurnIcon";
SDLImageFieldName const SDLImageFieldNameLocationImage = @"locationImage";
SDLImageFieldName const SDLImageFieldNameSubMenuIcon = @"subMenuIcon";
+SDLImageFieldName const SDLImageFieldNameSubtleAlertIcon = @"subtleAlertIcon";
diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h
index 277296d29..ce2b32392 100644
--- a/SmartDeviceLink/SDLNotificationConstants.h
+++ b/SmartDeviceLink/SDLNotificationConstants.h
@@ -315,6 +315,9 @@ extern SDLNotificationName const SDLDidReceiveSubscribeVehicleDataResponse;
/// Name for a SubscribeWaypoints response RPC
extern SDLNotificationName const SDLDidReceiveSubscribeWaypointsResponse;
+/// Name for a SubtleAlert response RPC
+extern SDLNotificationName const SDLDidReceiveSubtleAlertResponse;
+
/// Name for a SyncPData response RPC
extern SDLNotificationName const SDLDidReceiveSyncPDataResponse __deprecated;
@@ -506,9 +509,12 @@ extern SDLNotificationName const SDLDidReceiveSubscribeButtonRequest;
/// Name for a SubscribeVehicleData request RPC
extern SDLNotificationName const SDLDidReceiveSubscribeVehicleDataRequest;
-/// Name for a ubscribeWayPoints request RPC
+/// Name for a SubscribeWayPoints request RPC
extern SDLNotificationName const SDLDidReceiveSubscribeWayPointsRequest;
+/// Name for a SubtleAlert request RPC
+extern SDLNotificationName const SDLDidReceiveSubtleAlertRequest;
+
/// Name for a SyncPData request RPC
extern SDLNotificationName const SDLDidReceiveSyncPDataRequest __deprecated;
@@ -583,6 +589,9 @@ extern SDLNotificationName const SDLDidReceiveVehicleIconNotification;
/// Name for a ChangePermissions notification RPC
extern SDLNotificationName const SDLDidChangePermissionsNotification;
+/// Name for a SubtleAlertPressed notification RPC
+extern SDLNotificationName const SDLDidReceiveSubtleAlertPressedNotification;
+
/// Name for a RemoteControlStatus notification RPC
extern SDLNotificationName const SDLDidReceiveRemoteControlStatusNotification;
diff --git a/SmartDeviceLink/SDLNotificationConstants.m b/SmartDeviceLink/SDLNotificationConstants.m
index 980f6bd78..c0b0577ed 100644
--- a/SmartDeviceLink/SDLNotificationConstants.m
+++ b/SmartDeviceLink/SDLNotificationConstants.m
@@ -84,6 +84,7 @@ SDLNotificationName const SDLDidReceiveSpeakResponse = @"com.sdl.response.Speak"
SDLNotificationName const SDLDidReceiveSubscribeButtonResponse = @"com.sdl.response.SubscribeButton";
SDLNotificationName const SDLDidReceiveSubscribeVehicleDataResponse = @"com.sdl.response.SubscribeVehicleData";
SDLNotificationName const SDLDidReceiveSubscribeWaypointsResponse = @"com.sdl.response.SubscribeWayPoints";
+SDLNotificationName const SDLDidReceiveSubtleAlertResponse = @"com.sdl.response.SubtleAlert";
SDLNotificationName const SDLDidReceiveSyncPDataResponse = @"com.sdl.response.SyncPData";
SDLNotificationName const SDLDidReceiveSystemRequestResponse = @"com.sdl.response.SystemRequest";
SDLNotificationName const SDLDidReceiveUpdateTurnListResponse = @"com.sdl.response.UpdateTurnList";
@@ -149,6 +150,7 @@ SDLNotificationName const SDLDidReceiveSpeakRequest = @"com.sdl.request.Speak";
SDLNotificationName const SDLDidReceiveSubscribeButtonRequest = @"com.sdl.request.SubscribeButton";
SDLNotificationName const SDLDidReceiveSubscribeVehicleDataRequest = @"com.sdl.request.SubscribeVehicleData";
SDLNotificationName const SDLDidReceiveSubscribeWayPointsRequest = @"com.sdl.request.SubscribeWayPoints";
+SDLNotificationName const SDLDidReceiveSubtleAlertRequest = @"com.sdl.request.SubtleAlert";
SDLNotificationName const SDLDidReceiveSyncPDataRequest = @"com.sdl.request.SyncPData";
SDLNotificationName const SDLDidReceiveSystemRequestRequest = @"com.sdl.request.SystemRequest";
SDLNotificationName const SDLDidReceiveUnpublishAppServiceRequest = @"com.sdl.request.UnpublishAppService";
@@ -174,6 +176,7 @@ SDLNotificationName const SDLDidChangeLanguageNotification = @"com.sdl.notificat
SDLNotificationName const SDLDidReceiveNewHashNotification = @"com.sdl.notification.OnHashChange";
SDLNotificationName const SDLDidChangePermissionsNotification = @"com.sdl.notification.OnPermissionsChange";
SDLNotificationName const SDLDidReceiveRemoteControlStatusNotification = @"com.sdl.notification.OnRCStatus";
+SDLNotificationName const SDLDidReceiveSubtleAlertPressedNotification = @"com.sdl.notification.OnSubtleAlertPressed";
SDLNotificationName const SDLDidReceiveSyncPDataNotification = @"com.sdl.notification.OnSyncPData";
SDLNotificationName const SDLDidReceiveSystemCapabilityUpdatedNotification = @"com.sdl.notification.OnSystemCapabilityUpdated";
SDLNotificationName const SDLDidReceiveSystemRequestNotification = @"com.sdl.notification.OnSystemRequest";
@@ -251,6 +254,7 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLDidReceiveSyncPDataResponse,
#pragma clang diagnostic pop
+ SDLDidReceiveSubtleAlertResponse,
SDLDidReceiveSystemRequestResponse,
SDLDidReceiveUpdateTurnListResponse,
SDLDidReceiveUnpublishAppServiceResponse,
diff --git a/SmartDeviceLink/SDLOnSubtleAlertPressed.h b/SmartDeviceLink/SDLOnSubtleAlertPressed.h
new file mode 100644
index 000000000..8a924d19b
--- /dev/null
+++ b/SmartDeviceLink/SDLOnSubtleAlertPressed.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SDLRPCNotification.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * Sent when the alert itself is touched (outside of a soft button). Touching (or otherwise selecting) the alert should open the app before sending this notification.
+ *
+ * @since SDL 7.0.0
+ */
+@interface SDLOnSubtleAlertPressed : SDLRPCNotification
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLOnSubtleAlertPressed.m b/SmartDeviceLink/SDLOnSubtleAlertPressed.m
new file mode 100644
index 000000000..b89d7a38c
--- /dev/null
+++ b/SmartDeviceLink/SDLOnSubtleAlertPressed.m
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SDLOnSubtleAlertPressed.h"
+
+#import "NSMutableDictionary+Store.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLRPCParameterNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLOnSubtleAlertPressed
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ self = [super initWithName:SDLRPCFunctionNameOnSubtleAlertPressed];
+ if (!self) {
+ return nil;
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLRPCFunctionNames.h b/SmartDeviceLink/SDLRPCFunctionNames.h
index bd5a417d3..180b69ad8 100644
--- a/SmartDeviceLink/SDLRPCFunctionNames.h
+++ b/SmartDeviceLink/SDLRPCFunctionNames.h
@@ -145,6 +145,9 @@ extern SDLRPCFunctionName const SDLRPCFunctionNameOnPermissionsChange;
/// Function name for an OnRCStatus notification RPC
extern SDLRPCFunctionName const SDLRPCFunctionNameOnRCStatus;
+/// Function name for an SubtleAlertPressed notification RPC
+extern SDLRPCFunctionName const SDLRPCFunctionNameOnSubtleAlertPressed;
+
/// Function name for an OnSyncPData notification RPC
extern SDLRPCFunctionName const SDLRPCFunctionNameOnSyncPData __deprecated;
@@ -253,6 +256,9 @@ extern SDLRPCFunctionName const SDLRPCFunctionNameSubscribeVehicleData;
/// Function name for a SubscribeWayPoints RPC
extern SDLRPCFunctionName const SDLRPCFunctionNameSubscribeWayPoints;
+/// Function name for a SubtleAlert RPC
+extern SDLRPCFunctionName const SDLRPCFunctionNameSubtleAlert;
+
/// Function name for a SyncPData RPC
extern SDLRPCFunctionName const SDLRPCFunctionNameSyncPData __deprecated;
diff --git a/SmartDeviceLink/SDLRPCFunctionNames.m b/SmartDeviceLink/SDLRPCFunctionNames.m
index 5addc7798..a0a0c4754 100644
--- a/SmartDeviceLink/SDLRPCFunctionNames.m
+++ b/SmartDeviceLink/SDLRPCFunctionNames.m
@@ -52,6 +52,7 @@ SDLRPCFunctionName const SDLRPCFunctionNameOnLanguageChange = @"OnLanguageChange
SDLRPCFunctionName const SDLRPCFunctionNameOnLockScreenStatus = @"OnLockScreenStatus";
SDLRPCFunctionName const SDLRPCFunctionNameOnPermissionsChange = @"OnPermissionsChange";
SDLRPCFunctionName const SDLRPCFunctionNameOnRCStatus = @"OnRCStatus";
+SDLRPCFunctionName const SDLRPCFunctionNameOnSubtleAlertPressed = @"OnSubtleAlertPressed";
SDLRPCFunctionName const SDLRPCFunctionNameOnSyncPData = @"OnSyncPData";
SDLRPCFunctionName const SDLRPCFunctionNameOnSystemCapabilityUpdated = @"OnSystemCapabilityUpdated";
SDLRPCFunctionName const SDLRPCFunctionNameOnSystemRequest = @"OnSystemRequest";
@@ -88,6 +89,7 @@ SDLRPCFunctionName const SDLRPCFunctionNameSpeak = @"Speak";
SDLRPCFunctionName const SDLRPCFunctionNameSubscribeButton = @"SubscribeButton";
SDLRPCFunctionName const SDLRPCFunctionNameSubscribeVehicleData = @"SubscribeVehicleData";
SDLRPCFunctionName const SDLRPCFunctionNameSubscribeWayPoints = @"SubscribeWayPoints";
+SDLRPCFunctionName const SDLRPCFunctionNameSubtleAlert = @"SubtleAlert";
SDLRPCFunctionName const SDLRPCFunctionNameSyncPData = @"SyncPData";
SDLRPCFunctionName const SDLRPCFunctionNameSystemRequest = @"SystemRequest";
SDLRPCFunctionName const SDLRPCFunctionNameUnpublishAppService = @"UnpublishAppService";
diff --git a/SmartDeviceLink/SDLSubtleAlert.h b/SmartDeviceLink/SDLSubtleAlert.h
new file mode 100644
index 000000000..f49c0e2c9
--- /dev/null
+++ b/SmartDeviceLink/SDLSubtleAlert.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SDLRPCRequest.h"
+
+@class SDLImage;
+@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.
+ *
+ * @since SDL 7.0.0
+ */
+@interface SDLSubtleAlert : SDLRPCRequest
+
+/**
+ * @param alertText1 - alertText1
+ * @param alertText2 - alertText2
+ * @param alertIcon - alertIcon
+ * @param ttsChunks - ttsChunks
+ * @param duration - duration
+ * @param softButtons - softButtons
+ * @param cancelID - cancelID
+ * @return A SDLSubtleAlert object
+ */
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertIcon:(nullable SDLImage *)alertIcon ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks duration:(nullable NSNumber<SDLUInt> *)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons cancelID:(nullable NSNumber<SDLInt> *)cancelID;
+
+/**
+ * The first line of the alert text field
+ * {"default_value": null, "max_length": 500, "min_length": 1}
+ */
+@property (nullable, strong, nonatomic) NSString *alertText1;
+
+/**
+ * The second line of the alert text field
+ * {"default_value": null, "max_length": 500, "min_length": 1}
+ */
+@property (nullable, strong, nonatomic) NSString *alertText2;
+
+/**
+ * Image to be displayed for the corresponding alert. See Image. If omitted on supported displays, no (or the default if applicable) icon should be displayed.
+ */
+@property (nullable, strong, nonatomic) SDLImage *alertIcon;
+
+/**
+ * An array of text chunks of type TTSChunk. See TTSChunk. The array must have at least one item.
+ * {"default_value": null, "max_size": 100, "min_size": 1}
+ */
+@property (nullable, strong, nonatomic) NSArray<SDLTTSChunk *> *ttsChunks;
+
+/**
+ * Timeout in milliseconds. Typical timeouts are 3-5 seconds. If omitted, timeout is set to 5s.
+ * {"default_value": 5000, "max_value": 10000, "min_value": 3000}
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLUInt> *duration;
+
+/**
+ * App defined SoftButtons. If omitted on supported displays, the displayed alert shall not have any SoftButtons.
+ * {"default_value": null, "max_size": 2, "min_size": 0}
+ */
+@property (nullable, strong, nonatomic) NSArray<SDLSoftButton *> *softButtons;
+
+/**
+ * An ID for this specific alert to allow cancellation through the `CancelInteraction` RPC.
+ * {"default_value": null, "max_value": null, "min_value": null}
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLInt> *cancelID;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLSubtleAlert.m b/SmartDeviceLink/SDLSubtleAlert.m
new file mode 100644
index 000000000..651b92a2c
--- /dev/null
+++ b/SmartDeviceLink/SDLSubtleAlert.m
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SDLSubtleAlert.h"
+
+#import "NSMutableDictionary+Store.h"
+#import "SDLImage.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLSoftButton.h"
+#import "SDLTTSChunk.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLSubtleAlert
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ self = [super initWithName:SDLRPCFunctionNameSubtleAlert];
+ if (!self) {
+ return nil;
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertIcon:(nullable SDLImage *)alertIcon ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks duration:(nullable NSNumber<SDLUInt> *)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons cancelID:(nullable NSNumber<SDLInt> *)cancelID {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+ self.alertText1 = alertText1;
+ self.alertText2 = alertText2;
+ self.alertIcon = alertIcon;
+ self.ttsChunks = ttsChunks;
+ self.duration = duration;
+ self.softButtons = softButtons;
+ self.cancelID = cancelID;
+ return self;
+}
+
+- (void)setAlertText1:(nullable NSString *)alertText1 {
+ [self.parameters sdl_setObject:alertText1 forName:SDLRPCParameterNameAlertText1];
+}
+
+- (nullable NSString *)alertText1 {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameAlertText1 ofClass:NSString.class error:nil];
+}
+
+- (void)setAlertText2:(nullable NSString *)alertText2 {
+ [self.parameters sdl_setObject:alertText2 forName:SDLRPCParameterNameAlertText2];
+}
+
+- (nullable NSString *)alertText2 {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameAlertText2 ofClass:NSString.class error:nil];
+}
+
+- (void)setAlertIcon:(nullable SDLImage *)alertIcon {
+ [self.parameters sdl_setObject:alertIcon forName:SDLRPCParameterNameAlertIcon];
+}
+
+- (nullable SDLImage *)alertIcon {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameAlertIcon ofClass:SDLImage.class error:nil];
+}
+
+- (void)setTtsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks {
+ [self.parameters sdl_setObject:ttsChunks forName:SDLRPCParameterNameTTSChunks];
+}
+
+- (nullable NSArray<SDLTTSChunk *> *)ttsChunks {
+ return [self.parameters sdl_objectsForName:SDLRPCParameterNameTTSChunks ofClass:SDLTTSChunk.class error:nil];
+}
+
+- (void)setDuration:(nullable NSNumber<SDLUInt> *)duration {
+ [self.parameters sdl_setObject:duration forName:SDLRPCParameterNameDuration];
+}
+
+- (nullable NSNumber<SDLUInt> *)duration {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameDuration ofClass:NSNumber.class error:nil];
+}
+
+- (void)setSoftButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
+ [self.parameters sdl_setObject:softButtons forName:SDLRPCParameterNameSoftButtons];
+}
+
+- (nullable NSArray<SDLSoftButton *> *)softButtons {
+ 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/SDLSubtleAlertResponse.h b/SmartDeviceLink/SDLSubtleAlertResponse.h
new file mode 100644
index 000000000..00940a540
--- /dev/null
+++ b/SmartDeviceLink/SDLSubtleAlertResponse.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SDLRPCResponse.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * @since SDL 7.0.0
+ */
+@interface SDLSubtleAlertResponse : SDLRPCResponse
+
+/**
+ * @param tryAgainTime - tryAgainTime
+ * @return A SDLSubtleAlertResponse object
+ */
+- (instancetype)initWithTryAgainTime:(nullable NSNumber<SDLUInt> *)tryAgainTime;
+
+/**
+ * Amount of time (in milliseconds) that an app must wait before resending an alert. If provided, another system event or overlay currently has a higher priority than this alert. An app must not send an alert without waiting at least the amount of time dictated.
+ * {"default_value": null, "max_value": 2000000000, "min_value": 0}
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLUInt> *tryAgainTime;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLSubtleAlertResponse.m b/SmartDeviceLink/SDLSubtleAlertResponse.m
new file mode 100644
index 000000000..4bd9c4b5a
--- /dev/null
+++ b/SmartDeviceLink/SDLSubtleAlertResponse.m
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SDLSubtleAlertResponse.h"
+
+#import "NSMutableDictionary+Store.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLRPCParameterNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLSubtleAlertResponse
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ self = [super initWithName:SDLRPCFunctionNameSubtleAlert];
+ if (!self) {
+ return nil;
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+- (instancetype)initWithTryAgainTime:(nullable NSNumber<SDLUInt> *)tryAgainTime {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+ self.tryAgainTime = tryAgainTime;
+ return self;
+}
+
+- (void)setTryAgainTime:(nullable NSNumber<SDLUInt> *)tryAgainTime {
+ [self.parameters sdl_setObject:tryAgainTime forName:SDLRPCParameterNameTryAgainTime];
+}
+
+- (nullable NSNumber<SDLUInt> *)tryAgainTime {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameTryAgainTime ofClass:NSNumber.class error:nil];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLTextFieldName.h b/SmartDeviceLink/SDLTextFieldName.h
index 7827e4e2a..a61146aa6 100644
--- a/SmartDeviceLink/SDLTextFieldName.h
+++ b/SmartDeviceLink/SDLTextFieldName.h
@@ -1,6 +1,34 @@
-// SDLTextFieldName.h
-//
-
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#import "SDLEnum.h"
@@ -199,3 +227,24 @@ extern SDLTextFieldName const SDLTextFieldNameAddressLines;
* @since SDL 4.0
*/
extern SDLTextFieldName const SDLTextFieldNamePhoneNumber;
+
+/**
+ * The first line of the subtle alert text field; applies to `SubtleAlert` `alertText1`
+ *
+ * @since SDL 7.0.0
+ */
+extern SDLTextFieldName const SDLTextFieldNameSubtleAlertText1;
+
+/**
+ * The second line of the subtle alert text field; applies to `SubtleAlert` `alertText2`
+ *
+ * @since SDL 7.0.0
+ */
+extern SDLTextFieldName const SDLTextFieldNameSubtleAlertText2;
+
+/**
+ * A text field in the soft button of a subtle alert; applies to `SubtleAlert` `softButtons`
+ *
+ * @since SDL 7.0.0
+ */
+extern SDLTextFieldName const SDLTextFieldNameSubtleAlertSoftButtonText;
diff --git a/SmartDeviceLink/SDLTextFieldName.m b/SmartDeviceLink/SDLTextFieldName.m
index 3bb04fd4b..54f8c781e 100644
--- a/SmartDeviceLink/SDLTextFieldName.m
+++ b/SmartDeviceLink/SDLTextFieldName.m
@@ -1,6 +1,34 @@
-// SDLTextFieldName.m
-//
-
+/*
+ * Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#import "SDLTextFieldName.h"
@@ -33,3 +61,6 @@ SDLTextFieldName const SDLTextFieldNameLocationName = @"locationName";
SDLTextFieldName const SDLTextFieldNameLocationDescription = @"locationDescription";
SDLTextFieldName const SDLTextFieldNameAddressLines = @"addressLines";
SDLTextFieldName const SDLTextFieldNamePhoneNumber = @"phoneNumber";
+SDLTextFieldName const SDLTextFieldNameSubtleAlertText1 = @"subtleAlertText1";
+SDLTextFieldName const SDLTextFieldNameSubtleAlertText2 = @"subtleAlertText2";
+SDLTextFieldName const SDLTextFieldNameSubtleAlertSoftButtonText = @"subtleAlertSoftButtonText";
diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h
index 19a7dde87..ce0077dca 100644
--- a/SmartDeviceLink/SmartDeviceLink.h
+++ b/SmartDeviceLink/SmartDeviceLink.h
@@ -73,6 +73,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLSubscribeButton.h"
#import "SDLSubscribeVehicleData.h"
#import "SDLSubscribeWayPoints.h"
+#import "SDLSubtleAlert.h"
#import "SDLSyncPData.h"
#import "SDLSystemRequest.h"
#import "SDLUnpublishAppService.h"
@@ -139,6 +140,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLSubscribeButtonResponse.h"
#import "SDLSubscribeVehicleDataResponse.h"
#import "SDLSubscribeWayPointsResponse.h"
+#import "SDLSubtleAlertResponse.h"
#import "SDLSyncPDataResponse.h"
#import "SDLUnpublishAppServiceResponse.h"
#import "SDLReleaseInteriorVehicleDataModuleResponse.h"
@@ -165,6 +167,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLOnLockScreenStatus.h"
#import "SDLOnPermissionsChange.h"
#import "SDLOnRCStatus.h"
+#import "SDLOnSubtleAlertPressed.h"
#import "SDLOnSyncPData.h"
#import "SDLOnSystemCapabilityUpdated.h"
#import "SDLOnSystemRequest.h"
diff --git a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m
index 33383377b..6363714eb 100644
--- a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m
@@ -28,6 +28,7 @@ describe(@"Individual Enum Value Tests", ^ {
expect(SDLImageFieldNameShowConstantTBTNextTurnIcon).to(equal(@"showConstantTBTNextTurnIcon"));
expect(SDLImageFieldNameLocationImage).to(equal(@"locationImage"));
expect(SDLImageFieldNameSubMenuIcon).to(equal(@"subMenuIcon"));
+ expect(SDLImageFieldNameSubtleAlertIcon).to(equal(@"subtleAlertIcon"));
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m
index bacc79853..8f4b698fa 100644
--- a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m
@@ -43,6 +43,9 @@ describe(@"Individual Enum Value Tests", ^ {
expect(SDLTextFieldNameLocationDescription).to(equal(@"locationDescription"));
expect(SDLTextFieldNameAddressLines).to(equal(@"addressLines"));
expect(SDLTextFieldNamePhoneNumber).to(equal(@"phoneNumber"));
+ expect(SDLTextFieldNameSubtleAlertText1).to(equal(@"subtleAlertText1"));
+ expect(SDLTextFieldNameSubtleAlertText2).to(equal(@"subtleAlertText2"));
+ expect(SDLTextFieldNameSubtleAlertSoftButtonText).to(equal("subtleAlertSoftButtonText"));
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnSubtleAlertPressedSpec.m b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnSubtleAlertPressedSpec.m
new file mode 100644
index 000000000..e582242ed
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnSubtleAlertPressedSpec.m
@@ -0,0 +1,29 @@
+//
+// SDLOnSubtleAlertPressedSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Nicole on 7/28/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLOnSubtleAlertPressed.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLRPCFunctionNames.h"
+
+QuickSpecBegin(SDLOnSubtleAlertPressedSpec)
+
+describe(@"Getter/Setter Tests", ^{
+ __block SDLOnSubtleAlertPressed *testOnSubtleAlertPressed = nil;
+
+ it(@"Should init correctly", ^{
+ testOnSubtleAlertPressed = [[SDLOnSubtleAlertPressed alloc] init];
+
+ expect(testOnSubtleAlertPressed).toNot(beNil());
+ });
+});
+
+QuickSpecEnd
+
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m
index c36c5de29..f8f1be402 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLCancelInteractionSpec.m
@@ -103,6 +103,13 @@ describe(@"Getter/Setter Tests", ^{
expect(testRequest.cancelID).to(equal(testCancelID));
});
+ it(@"Should initialize correctly with initWithSubtleAlertCancelID:", ^{
+ testRequest = [[SDLCancelInteraction alloc] initWithSubtleAlertCancelID:testCancelID];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSubtleAlert]));
+ expect(testRequest.cancelID).to(equal(testCancelID));
+ });
+
it(@"Should initialize correctly with alert:", ^{
testRequest = [SDLCancelInteraction alert];
@@ -130,6 +137,13 @@ describe(@"Getter/Setter Tests", ^{
expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNamePerformInteraction]));
expect(testRequest.cancelID).to(beNil());
});
+
+ it(@"Should initialize correctly with subtleAlert:", ^{
+ testRequest = [SDLCancelInteraction subtleAlert];
+
+ expect(testRequest.functionID).to(equal([SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameSubtleAlert]));
+ expect(testRequest.cancelID).to(beNil());
+ });
});
afterEach(^{
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSubtleAlertSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSubtleAlertSpec.m
new file mode 100644
index 000000000..e91352d48
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLSubtleAlertSpec.m
@@ -0,0 +1,107 @@
+//
+// SDLSubtleAlertSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Nicole on 7/28/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLImage.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLSoftButton.h"
+#import "SDLSubtleAlert.h"
+#import "SDLTTSChunk.h"
+
+QuickSpecBegin(SDLSubtleAlertSpec)
+
+describe(@"Getter/Setter Tests", ^{
+ __block SDLSubtleAlert *testSubtleAlert = nil;
+ __block NSString *testAlertText1 = nil;
+ __block NSString *testAlertText2 = nil;
+ __block SDLImage *testAlertIcon = nil;
+ __block NSArray<SDLTTSChunk *> *testTTSChunks = nil;
+ __block int testDuration = 5600;
+ __block NSArray<SDLSoftButton *> *testSoftButtons = nil;
+ __block int testCancelID = 34;
+
+ beforeEach(^{
+ testAlertText1 = @"test alert text 1";
+ testAlertText2 = @"test alert text 2";
+ testAlertIcon = [[SDLImage alloc] initWithStaticIconName:SDLStaticIconNameKey];
+ testTTSChunks = [SDLTTSChunk textChunksFromString:@"alert text"];
+ testSoftButtons = @[[[SDLSoftButton alloc] init]];
+ });
+
+ it(@"Should set and get correctly", ^{
+ testSubtleAlert = [[SDLSubtleAlert alloc] init];
+ testSubtleAlert.alertText1 = testAlertText1;
+ testSubtleAlert.alertText2 = testAlertText2;
+ testSubtleAlert.alertIcon = testAlertIcon;
+ testSubtleAlert.ttsChunks = testTTSChunks;
+ testSubtleAlert.duration = @(testDuration);
+ testSubtleAlert.softButtons = testSoftButtons;
+ testSubtleAlert.cancelID = @(testCancelID);
+
+ expect(testSubtleAlert.alertText1).to(equal(testAlertText1));
+ expect(testSubtleAlert.alertText2).to(equal(testAlertText2));
+ expect(testSubtleAlert.alertIcon).to(equal(testAlertIcon));
+ expect(testSubtleAlert.ttsChunks).to(equal(testTTSChunks));
+ expect(testSubtleAlert.duration).to(equal(testDuration));
+ expect(testSubtleAlert.softButtons).to(equal(testSoftButtons));
+ expect(testSubtleAlert.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with a dictionary", ^{
+ NSDictionary *dict = @{SDLRPCParameterNameRequest:@{
+ SDLRPCParameterNameParameters:@{
+ SDLRPCParameterNameAlertText1:testAlertText1,
+ SDLRPCParameterNameAlertText2:testAlertText2,
+ SDLRPCParameterNameAlertIcon:testAlertIcon,
+ SDLRPCParameterNameTTSChunks:testTTSChunks,
+ SDLRPCParameterNameDuration:@(testDuration),
+ SDLRPCParameterNameSoftButtons:testSoftButtons,
+ SDLRPCParameterNameCancelID:@(testCancelID)
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameSubtleAlert}};
+ testSubtleAlert = [[SDLSubtleAlert alloc] initWithDictionary:dict];
+
+ expect(testSubtleAlert.alertText1).to(equal(testAlertText1));
+ expect(testSubtleAlert.alertText2).to(equal(testAlertText2));
+ expect(testSubtleAlert.alertIcon).to(equal(testAlertIcon));
+ expect(testSubtleAlert.ttsChunks).to(equal(testTTSChunks));
+ expect(testSubtleAlert.duration).to(equal(testDuration));
+ expect(testSubtleAlert.softButtons).to(equal(testSoftButtons));
+ expect(testSubtleAlert.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should initialize correctly with initWithAlertText1:alertText2:alertIcon:ttsChunks:duration:softButtons:cancelID:", ^{
+ testSubtleAlert = [[SDLSubtleAlert alloc] initWithAlertText1:testAlertText1 alertText2:testAlertText2 alertIcon:testAlertIcon ttsChunks:testTTSChunks duration:@(testDuration) softButtons:testSoftButtons cancelID:@(testCancelID)];
+
+ expect(testSubtleAlert.alertText1).to(equal(testAlertText1));
+ expect(testSubtleAlert.alertText2).to(equal(testAlertText2));
+ expect(testSubtleAlert.alertIcon).to(equal(testAlertIcon));
+ expect(testSubtleAlert.ttsChunks).to(equal(testTTSChunks));
+ expect(testSubtleAlert.duration).to(equal(testDuration));
+ expect(testSubtleAlert.softButtons).to(equal(testSoftButtons));
+ expect(testSubtleAlert.cancelID).to(equal(testCancelID));
+ });
+
+ it(@"Should return nil if not set", ^{
+ testSubtleAlert = [[SDLSubtleAlert alloc] init];
+
+ expect(testSubtleAlert.alertText1).to(beNil());
+ expect(testSubtleAlert.alertText2).to(beNil());
+ expect(testSubtleAlert.alertIcon).to(beNil());
+ expect(testSubtleAlert.ttsChunks).to(beNil());
+ expect(testSubtleAlert.duration).to(beNil());
+ expect(testSubtleAlert.softButtons).to(beNil());
+ expect(testSubtleAlert.cancelID).to(beNil());
+ });
+});
+
+QuickSpecEnd
+
diff --git a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLSubtleAlertResponseSpec.m b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLSubtleAlertResponseSpec.m
new file mode 100644
index 000000000..71cda2959
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLSubtleAlertResponseSpec.m
@@ -0,0 +1,54 @@
+//
+// SDLSubtleAlertResponseSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Nicole on 7/28/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLRPCFunctionNames.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLSubtleAlertResponse.h"
+
+QuickSpecBegin(SDLSubtleAlertResponseSpec)
+
+describe(@"Getter/Setter Tests", ^{
+ __block SDLSubtleAlertResponse *testSubtleAlertResponse = nil;
+ __block int testTryAgainTime = 6;
+
+ it(@"Should set and get correctly", ^{
+ testSubtleAlertResponse = [[SDLSubtleAlertResponse alloc] init];
+ testSubtleAlertResponse.tryAgainTime = @(testTryAgainTime);
+
+ expect(testSubtleAlertResponse.tryAgainTime).to(equal(testTryAgainTime));
+ });
+
+ it(@"Should get correctly when initialized with a dictionary", ^{
+ NSDictionary *dict = @{SDLRPCParameterNameResponse:@{
+ SDLRPCParameterNameParameters:@{
+ SDLRPCParameterNameTryAgainTime:@(testTryAgainTime)
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameSubtleAlert}};
+ testSubtleAlertResponse = [[SDLSubtleAlertResponse alloc] initWithDictionary:dict];
+
+ expect(testSubtleAlertResponse.tryAgainTime).to(equal(testTryAgainTime));
+ });
+
+ it(@"Should get correctly when initialized with initWithTryAgainTime:", ^{
+ testSubtleAlertResponse = [[SDLSubtleAlertResponse alloc] initWithTryAgainTime:@(testTryAgainTime)];
+
+ expect(testSubtleAlertResponse.tryAgainTime).to(equal(testTryAgainTime));
+ });
+
+ it(@"Should return nil if not set", ^{
+ testSubtleAlertResponse = [[SDLSubtleAlertResponse alloc] init];
+
+ expect(testSubtleAlertResponse.tryAgainTime).to(beNil());
+ });
+});
+
+QuickSpecEnd
+
diff --git a/SmartDeviceLink_Example/SubscribeButtonManager.m b/SmartDeviceLink_Example/SubscribeButtonManager.m
index 80512a7b2..cbe819288 100644
--- a/SmartDeviceLink_Example/SubscribeButtonManager.m
+++ b/SmartDeviceLink_Example/SubscribeButtonManager.m
@@ -56,8 +56,7 @@ NS_ASSUME_NONNULL_BEGIN
alertMessage = [NSString stringWithFormat:@"%@ long pressed", buttonName];
}
- SDLAlert *alert = [AlertManager alertWithMessageAndCloseButton:alertMessage textField2:nil iconName:nil];
- [self.sdlManager sendRPC:alert];
+ [AlertManager sendAlertWithManager:self.sdlManager image:nil textField1:alertMessage textField2:nil];
}
+ (NSArray<SDLButtonName> *)sdlex_allPresetButtons {
diff --git a/SmartDeviceLink_Example/SubscribeButtonManager.swift b/SmartDeviceLink_Example/SubscribeButtonManager.swift
index 6567d9e64..1bf128c1d 100644
--- a/SmartDeviceLink_Example/SubscribeButtonManager.swift
+++ b/SmartDeviceLink_Example/SubscribeButtonManager.swift
@@ -38,16 +38,13 @@ class SubscribeButtonManager: NSObject {
guard let buttonPress = buttonPress else { return }
- let alert: SDLAlert
let buttonNameString = buttonName.rawValue.rawValue
switch buttonPress.buttonPressMode {
case .short:
- alert = AlertManager.alertWithMessageAndCloseButton("\(buttonNameString) short pressed")
+ AlertManager.sendAlert(textField1: "\(buttonNameString) short pressed", sdlManager: sdlManager)
case .long:
- alert = AlertManager.alertWithMessageAndCloseButton("\(buttonNameString) long pressed")
+ AlertManager.sendAlert(textField1: "\(buttonNameString) long pressed", sdlManager: sdlManager)
default: fatalError()
}
-
- sdlManager.send(alert)
}
}
diff --git a/generator/transformers/common_producer.py b/generator/transformers/common_producer.py
index 59dbac4c3..13b56fd11 100644
--- a/generator/transformers/common_producer.py
+++ b/generator/transformers/common_producer.py
@@ -32,7 +32,7 @@ class InterfaceProducerCommon(ABC):
'origin constructor_argument constructor_prefix deprecated mandatory since '
'method_suffix of_class type_native type_sdl modifier for_name description '
'constructor_argument_override')
- self.constructor_named = namedtuple('constructor', 'init self arguments all deprecated')
+ self.constructor_named = namedtuple('constructor', 'init self arguments all')
self.argument_named = namedtuple('argument', 'origin constructor_argument variable deprecated')
self.names = self.struct_names + tuple(map(lambda e: self._replace_sync(e), enum_names))
@@ -175,7 +175,7 @@ class InterfaceProducerCommon(ABC):
def parentheses(self, item):
"""
Used for wrapping appropriate initiator (constructor) parameter with '@({})'
- :param item: named tup[le with initiator (constructor) parameter
+ :param item: named tuple with initiator (constructor) parameter
:return: wrapped parameter
"""
if re.match(r'\w*Int\d+|BOOL|float|double', item.type_native) or \
@@ -215,8 +215,10 @@ class InterfaceProducerCommon(ABC):
"""
mandatory = []
not_mandatory = []
- deprecated = any([m.deprecated for m in data.values() if getattr(m, 'deprecated', False)])
for param in data.values():
+ if param.deprecated:
+ # Omit deprecated parameters from the constructors
+ continue
if param.mandatory:
mandatory.append(param)
else:
@@ -225,13 +227,11 @@ class InterfaceProducerCommon(ABC):
result = []
if mandatory:
mandatory = self.extract_constructor(mandatory, True)
- mandatory['deprecated'] = deprecated
else:
mandatory = OrderedDict()
if not_mandatory:
not_mandatory = self.extract_constructor(not_mandatory, False)
- not_mandatory['deprecated'] = deprecated
if mandatory:
not_mandatory['init'] = '{} {}'.format(mandatory['init'], self.minimize_first(not_mandatory['init']))
not_mandatory['all'] = mandatory['arguments'] + not_mandatory['arguments']
@@ -337,9 +337,57 @@ class InterfaceProducerCommon(ABC):
'mandatory': param.is_mandatory,
'deprecated': json.loads(param.deprecated.lower()) if param.deprecated else False,
'modifier': 'strong'}
- if isinstance(param.param_type, (Integer, Float, String)):
- data['description'].append(json.dumps(vars(param.param_type), sort_keys=True))
+ if isinstance(param.param_type, (Integer, Float, String, Array)):
+ data['description'].append(self.create_param_descriptor(param.param_type, OrderedDict()))
data.update(self.extract_type(param))
data.update(self.param_origin_change(param.name))
return self.param_named(**data)
+
+ def create_param_descriptor(self, param_type, parameterItems):
+ """
+ Recursively creates a documentation string of all the descriptors for a parameter (e.g. {"string_min_length": 1, string_max_length": 500}). The parameters should be returned in the same order they were added to the parameterItems dictionary
+ :param param_type: param_type from the initial Model
+ :param parameterItems: Ordered dictionary that stores each of the parameter's descriptors
+ :return: All the descriptor params from param_type concatenated into one string
+ """
+ # The key is a descriptor (i.e. max_value) and value is the associated value (i.e. 100). Some values will be dictionaries that have to be parsed to get additional descriptors (e.g. the value for an array of strings' data type will be sub-dictionary describing the min_length, max_length, and default value for the strings used in the array)
+ for key, value in param_type.__dict__.items():
+ # If a value contains a dictionary, recurse until all the descriptors have been found. Once a descriptor (i.e. `max_size`) has been found along with its associated value (i.e. 100), add the descriptor/value pair to the parameterItems dictionary
+ if hasattr(value, '__dict__'):
+ if isinstance(value, Enum) or isinstance(value, Struct):
+ # Skip adding documentation for the data type if it is a struct or enum. This is unnecessary as each enum or struct has its own documentation
+ continue
+ else:
+ self.create_param_descriptor(value, parameterItems)
+ else:
+ if key == 'default_value' and value is None:
+ # Do not add the default_value key/value pair unless it has been explicitly set in the RPC Spec
+ continue
+ else:
+ parameterDescriptor = self.update_param_descriptor(key)
+ parameterItems[parameterDescriptor] = value
+
+ return json.dumps(parameterItems, sort_keys=False)
+
+ def update_param_descriptor(self, parameterName):
+ """
+ Updates the parameter's descriptor name for clarity. This is helpful for array documentation as the descriptors can contain both the size of the array and the size of the array's data type
+ :param parameterName: The name of the parameter
+ :return: All the descriptor params from param_type concatenated into one string
+ """
+ if parameterName == 'min_size':
+ return 'array_min_size'
+ elif parameterName == 'max_size':
+ return 'array_max_size'
+ elif parameterName == 'min_length':
+ return 'string_min_length'
+ elif parameterName == 'max_length':
+ return 'string_max_length'
+ elif parameterName == 'max_value':
+ return 'num_max_value'
+ elif parameterName == 'min_value':
+ return 'num_min_value'
+ else:
+ return parameterName
+