diff options
44 files changed, 1288 insertions, 219 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 fd22008df..c7ee4f44f 100644 --- a/SmartDeviceLink-iOS.podspec +++ b/SmartDeviceLink-iOS.podspec @@ -251,6 +251,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', @@ -377,6 +378,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 1bae109fe..ca3b7adae 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1425,6 +1425,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 */; }; @@ -3210,6 +3219,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>"; }; @@ -3728,6 +3746,7 @@ 162E82341A9BDE8A00906325 /* SDLOnLockScreenStatusSpec.m */, 162E82351A9BDE8A00906325 /* SDLOnPermissionsChangeSpec.m */, 1EAA470D2032BF1D000FE74B /* SDLOnRCStatusSpec.m */, + 889D0B9D24D07FF8008AD494 /* SDLOnSubtleAlertPressedSpec.m */, 162E82361A9BDE8A00906325 /* SDLOnSyncPDataSpec.m */, 88A5E7F3220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m */, 162E82371A9BDE8A00906325 /* SDLOnSystemRequestSpec.m */, @@ -3799,6 +3818,7 @@ 162E825D1A9BDE8A00906325 /* SDLSubscribeButtonSpec.m */, 162E825E1A9BDE8A00906325 /* SDLSubscribeVehicleDataSpec.m */, DA9F7EA31DCC05EE00ACAE48 /* SDLSubscribeWaypointsSpec.m */, + 889D0B9724D06E52008AD494 /* SDLSubtleAlertSpec.m */, 162E825F1A9BDE8A00906325 /* SDLSyncPDataSpec.m */, 162E82601A9BDE8A00906325 /* SDLSystemRequestSpec.m */, 162E82611A9BDE8A00906325 /* SDLUnregisterAppInterfaceSpec.m */, @@ -3873,6 +3893,7 @@ 162E82861A9BDE8A00906325 /* SDLSubscribeButtonResponseSpec.m */, 162E82871A9BDE8A00906325 /* SDLSubscribeVehicleDataResponseSpec.m */, DA9F7EA91DCC061A00ACAE48 /* SDLSubscribeWaypointsResponseSpec.m */, + 889D0B9524D065EE008AD494 /* SDLSubtleAlertResponseSpec.m */, 162E82881A9BDE8A00906325 /* SDLSyncPDataResponseSpec.m */, 162E82891A9BDE8A00906325 /* SDLSystemRequestResponseSpec.m */, 162E828A1A9BDE8A00906325 /* SDLUnregisterAppInterfaceResponseSpec.m */, @@ -4689,6 +4710,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 */, @@ -4824,6 +4847,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 */, @@ -5364,6 +5389,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 */, @@ -6870,6 +6897,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 */, @@ -7037,6 +7065,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 */, @@ -7047,6 +7076,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 */, @@ -7672,6 +7702,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 */, @@ -7698,6 +7729,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 */, @@ -7936,6 +7968,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 */, @@ -8334,6 +8367,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 */, @@ -8355,6 +8389,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 */, @@ -8475,6 +8510,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 7983acc58..4c578becc 100644 --- a/SmartDeviceLink.podspec +++ b/SmartDeviceLink.podspec @@ -255,6 +255,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', @@ -381,6 +382,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 1a3b93bbb..54be8ec07 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, #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @65536: SDLRPCFunctionNameEncodedSyncPData, diff --git a/SmartDeviceLink/SDLImageFieldName.h b/SmartDeviceLink/SDLImageFieldName.h index cd3e101c9..bffe33fa1 100644 --- a/SmartDeviceLink/SDLImageFieldName.h +++ b/SmartDeviceLink/SDLImageFieldName.h @@ -1,11 +1,39 @@ -// SDLImageFieldName.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" /** - The name that identifies the filed. Used in DisplayCapabilities. + The name that identifies the field. Used in DisplayCapabilities. @since SmartDeviceLink 3.0 */ @@ -82,3 +110,10 @@ extern SDLImageFieldName const SDLImageFieldNameShowConstantTBTNextTurnIcon; @since SDL 4.0 */ extern SDLImageFieldName const SDLImageFieldNameLocationImage; + +/** + * 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 0282f25b6..b6932f4cb 100644 --- a/SmartDeviceLink/SDLImageFieldName.m +++ b/SmartDeviceLink/SDLImageFieldName.m @@ -1,6 +1,34 @@ -// SDLImageFieldName.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 "SDLImageFieldName.h" @@ -18,3 +46,4 @@ SDLImageFieldName const SDLImageFieldNameSecondaryGraphic = @"secondaryGraphic"; SDLImageFieldName const SDLImageFieldNameShowConstantTBTIcon = @"showConstantTBTIcon"; SDLImageFieldName const SDLImageFieldNameShowConstantTBTNextTurnIcon = @"showConstantTBTNextTurnIcon"; SDLImageFieldName const SDLImageFieldNameLocationImage = @"locationImage"; +SDLImageFieldName const SDLImageFieldNameSubtleAlertIcon = @"subtleAlertIcon"; diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h index d99e0724c..7cb20dca1 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 d4cb7c9bc..14cba1c6f 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"; @@ -249,6 +252,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 fce4b61f7..a7c985c6c 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; @@ -247,6 +250,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 744922420..f4d115210 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"; @@ -86,6 +87,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 cb305d759..1c5aba623 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 bf3e9f82f..8b0406140 100644 --- a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLImageFieldNameSpec.m @@ -27,6 +27,7 @@ describe(@"Individual Enum Value Tests", ^ { expect(SDLImageFieldNameShowConstantTBTIcon).to(equal(@"showConstantTBTIcon")); expect(SDLImageFieldNameShowConstantTBTNextTurnIcon).to(equal(@"showConstantTBTNextTurnIcon")); expect(SDLImageFieldNameLocationImage).to(equal(@"locationImage")); + 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) } } |