diff options
author | NicoleYarroch <nicole@livio.io> | 2019-02-21 16:08:17 -0500 |
---|---|---|
committer | NicoleYarroch <nicole@livio.io> | 2019-02-21 16:08:17 -0500 |
commit | 8079cd4be14c0e3d61a4648005e1d0b2aecc4c90 (patch) | |
tree | 7694f0a8fe4f4ac6d8d8d6a895f3161e05527ff7 | |
parent | f1f2d968630266cf83cbbc4751cddb7e5f358394 (diff) | |
parent | 399a880d1dd739b13c706d5c7482e610bab7b4aa (diff) | |
download | sdl_ios-feature/issue_1147_and_1148_app_services_weather_media.tar.gz |
Merge branch 'feature/issue_1147_and_1148_app_services_handle_requests_send_responses' into feature/issue_1147_and_1148_app_services_weather_mediafeature/issue_1147_and_1148_app_services_weather_media
# Conflicts:
# SmartDeviceLink-iOS.xcodeproj/project.pbxproj
43 files changed, 790 insertions, 60 deletions
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec index 160f97cd5..499e5ea2f 100644 --- a/SmartDeviceLink-iOS.podspec +++ b/SmartDeviceLink-iOS.podspec @@ -275,6 +275,7 @@ ss.public_header_files = [ 'SmartDeviceLink/SDLRPCNotification.h', 'SmartDeviceLink/SDLRPCNotificationNotification.h', 'SmartDeviceLink/SDLRPCRequest.h', +'SmartDeviceLink/SDLRPCRequestNotification.h', 'SmartDeviceLink/SDLRPCResponse.h', 'SmartDeviceLink/SDLRPCResponseNotification.h', 'SmartDeviceLink/SDLRPCStruct.h', diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 517b70ad7..6f78ca23b 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1282,6 +1282,8 @@ 88802FF520853CD500E9EBC6 /* SmartDeviceLinkSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88802FEF20853AE600E9EBC6 /* SmartDeviceLinkSwift.framework */; }; 88802FF620853CD500E9EBC6 /* SmartDeviceLinkSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 88802FEF20853AE600E9EBC6 /* SmartDeviceLinkSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8886EB982111F4FA008294A5 /* SDLFileManagerConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8886EB972111F4FA008294A5 /* SDLFileManagerConfigurationSpec.m */; }; + 888F86FE221DEE200052FE4C /* SDLRPCResponseOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FD221DEE1F0052FE4C /* SDLRPCResponseOperation.m */; }; + 888F8700221DF4880052FE4C /* SDLRPCResponseOperationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FF221DF4880052FE4C /* SDLRPCResponseOperationSpec.m */; }; 88A1CF1E21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88A1CF1D21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m */; }; 88A5E7F4220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88A5E7F3220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m */; }; 88A5E7F7220B5BBC00495E8A /* SDLGetAppServiceData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88A5E7F5220B5BBC00495E8A /* SDLGetAppServiceData.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1337,6 +1339,10 @@ 88F65133220C6DC300CAF321 /* SDLWeatherAlertSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */; }; 88F65136220C74FD00CAF321 /* SDLWeatherData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F65134220C74FD00CAF321 /* SDLWeatherData.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88F65137220C74FD00CAF321 /* SDLWeatherData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65135220C74FD00CAF321 /* SDLWeatherData.m */; }; + 88F89103221DE29A00E056AD /* SDLRPCResponseOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F89101221DE29A00E056AD /* SDLRPCResponseOperation.h */; }; + 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 88FF4E772215FB8200A71361 /* SDLRPCRequestNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */; }; + 88FF4E7C2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */; }; 8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8B7B319B1F2F7B5700BDC38D /* SDLVideoStreamingCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */; }; 8B7B319E1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2734,8 +2740,8 @@ 5DB9965B1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartService.m; sourceTree = "<group>"; }; 5DB9965E1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadVideoStartServiceAck.h; sourceTree = "<group>"; }; 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartServiceAck.m; sourceTree = "<group>"; }; - 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLNotificationDispatcherSpec.m; path = DevAPISpecs/SDLNotificationDispatcherSpec.m; sourceTree = "<group>"; }; - 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLResponseDispatcherSpec.m; path = DevAPISpecs/SDLResponseDispatcherSpec.m; sourceTree = "<group>"; }; + 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLNotificationDispatcherSpec.m; sourceTree = "<group>"; }; + 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLResponseDispatcherSpec.m; sourceTree = "<group>"; }; 5DBEFA531F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLStreamingMediaConfigurationSpec.m; path = DevAPISpecs/SDLStreamingMediaConfigurationSpec.m; sourceTree = "<group>"; }; 5DBEFA561F436132009EE295 /* SDLFakeSecurityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLFakeSecurityManager.h; path = DevAPISpecs/SDLFakeSecurityManager.h; sourceTree = "<group>"; }; 5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLFakeSecurityManager.m; path = DevAPISpecs/SDLFakeSecurityManager.m; sourceTree = "<group>"; }; @@ -2857,6 +2863,8 @@ 8877F5F01F34AA2D00DC128A /* SDLSendHapticDataResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSendHapticDataResponseSpec.m; sourceTree = "<group>"; }; 88802FEF20853AE600E9EBC6 /* SmartDeviceLinkSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SmartDeviceLinkSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8886EB972111F4FA008294A5 /* SDLFileManagerConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLFileManagerConfigurationSpec.m; sourceTree = "<group>"; }; + 888F86FD221DEE1F0052FE4C /* SDLRPCResponseOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRPCResponseOperation.m; sourceTree = "<group>"; }; + 888F86FF221DF4880052FE4C /* SDLRPCResponseOperationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCResponseOperationSpec.m; sourceTree = "<group>"; }; 88A1CF1D21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLLifecycleConfigurationUpdateSpec.m; sourceTree = "<group>"; }; 88A5E7F3220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLOnSystemCapabilityUpdatedSpec.m; sourceTree = "<group>"; }; 88A5E7F5220B5BBC00495E8A /* SDLGetAppServiceData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLGetAppServiceData.h; sourceTree = "<group>"; }; @@ -2914,6 +2922,10 @@ 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherAlertSpec.m; sourceTree = "<group>"; }; 88F65134220C74FD00CAF321 /* SDLWeatherData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLWeatherData.h; sourceTree = "<group>"; }; 88F65135220C74FD00CAF321 /* SDLWeatherData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherData.m; sourceTree = "<group>"; }; + 88F89101221DE29A00E056AD /* SDLRPCResponseOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLRPCResponseOperation.h; sourceTree = "<group>"; }; + 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLRPCRequestNotification.h; sourceTree = "<group>"; }; + 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestNotification.m; sourceTree = "<group>"; }; + 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestNotificationSpec.m; sourceTree = "<group>"; }; 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingCodec.h; sourceTree = "<group>"; }; 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingCodec.m; sourceTree = "<group>"; }; 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingProtocol.h; sourceTree = "<group>"; }; @@ -3564,6 +3576,8 @@ 5D07C0302044AD0C00D1ECDC /* SDLAsynchronousRPCRequestOperation.m */, 5D07C02B2044AC9000D1ECDC /* SDLSequentialRPCRequestOperation.h */, 5D07C02C2044AC9100D1ECDC /* SDLSequentialRPCRequestOperation.m */, + 88F89101221DE29A00E056AD /* SDLRPCResponseOperation.h */, + 888F86FD221DEE1F0052FE4C /* SDLRPCResponseOperation.m */, ); name = "Request Operations"; sourceTree = "<group>"; @@ -3640,6 +3654,7 @@ 5D60DF23202B7A80001EDA01 /* SDLAsynchronousRPCRequestOperationSpec.m */, 5D60DF25202B7A97001EDA01 /* SDLSequentialRPCRequestOperationSpec.m */, 88A1CF1D21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m */, + 888F86FF221DF4880052FE4C /* SDLRPCResponseOperationSpec.m */, ); name = Lifecycle; sourceTree = "<group>"; @@ -5399,6 +5414,7 @@ 5DBAE0A71D355F0C00CE00BF /* Dispatchers */ = { isa = PBXGroup; children = ( + 88FF4E732215FB5B00A71361 /* Requests */, 5D3E48781D6F86EC0000BFEF /* Notifications */, 5D3E48821D74813B0000BFEF /* Responses */, ); @@ -5423,8 +5439,8 @@ 5DBAE0A91D35888D00CE00BF /* Dispatchers */ = { isa = PBXGroup; children = ( - 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */, - 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */, + 88FF4E7A2215FEC200A71361 /* Requests */, + 88FF4E792215FEAF00A71361 /* Notifications */, ); name = Dispatchers; sourceTree = "<group>"; @@ -5749,6 +5765,32 @@ path = iAP; sourceTree = "<group>"; }; + 88FF4E732215FB5B00A71361 /* Requests */ = { + isa = PBXGroup; + children = ( + 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */, + 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */, + ); + path = Requests; + sourceTree = "<group>"; + }; + 88FF4E792215FEAF00A71361 /* Notifications */ = { + isa = PBXGroup; + children = ( + 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */, + 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */, + ); + path = Notifications; + sourceTree = "<group>"; + }; + 88FF4E7A2215FEC200A71361 /* Requests */ = { + isa = PBXGroup; + children = ( + 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */, + ); + path = Requests; + sourceTree = "<group>"; + }; DA1166D71D14601C00438CEA /* Touches */ = { isa = PBXGroup; children = ( @@ -6366,10 +6408,12 @@ 5D61FCBF1A84238C00846EE7 /* SDLHexUtility.h in Headers */, 5D00AC6B1F141339004000D9 /* SDLSystemCapability.h in Headers */, 5DCD7AE01FCCA8D200A0FC7F /* SDLCarWindow.h in Headers */, + 88F89103221DE29A00E056AD /* SDLRPCResponseOperation.h in Headers */, 5D61FD6F1A84238C00846EE7 /* SDLRPCPayload.h in Headers */, 5D339CF3207C0ACE000CC364 /* SDLMenuManager.h in Headers */, 5D61FCF01A84238C00846EE7 /* SDLLockScreenStatusManager.h in Headers */, 5D61FD311A84238C00846EE7 /* SDLPolicyDataParser.h in Headers */, + 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6716,6 +6760,7 @@ 5D61FE101A84238C00846EE7 /* SDLVrHelpItem.m in Sources */, 5D07C0322044AD0C00D1ECDC /* SDLAsynchronousRPCRequestOperation.m in Sources */, 1E5AD0691F2080B50029B8AF /* SDLRadioControlData.m in Sources */, + 888F86FE221DEE200052FE4C /* SDLRPCResponseOperation.m in Sources */, 5D61FCC01A84238C00846EE7 /* SDLHexUtility.m in Sources */, 5DB9964F1F26886C002D8795 /* SDLControlFramePayloadEndService.m in Sources */, 5D61FD821A84238C00846EE7 /* SDLSetAppIconResponse.m in Sources */, @@ -6888,6 +6933,7 @@ 5DBF062E1E64A93A00A5CF03 /* SDLLogFilter.m in Sources */, 5D61FDFA1A84238C00846EE7 /* SDLV2ProtocolHeader.m in Sources */, 5D61FDD01A84238C00846EE7 /* SDLTireStatus.m in Sources */, + 88FF4E772215FB8200A71361 /* SDLRPCRequestNotification.m in Sources */, 5D92935F20B33FF700FCC775 /* SDLChoiceSet.m in Sources */, 8855F9E4220CB04000A5C897 /* SDLOnAppServiceData.m in Sources */, 5D61FC321A84238C00846EE7 /* SDLAddSubMenu.m in Sources */, @@ -7124,6 +7170,7 @@ 5D6EB4CC1BF28DC600693731 /* NSMapTable+SubscriptingSpec.m in Sources */, 162E83051A9BDE8B00906325 /* SDLVehicleDataActiveStatusSpec.m in Sources */, 162E82E61A9BDE8B00906325 /* SDLInteractionModeSpec.m in Sources */, + 888F8700221DF4880052FE4C /* SDLRPCResponseOperationSpec.m in Sources */, 162E83931A9BDE8B00906325 /* SDLTouchEventSpec.m in Sources */, 5DCF76FE1ACDDB5A00BB647B /* SDLSendLocationResponseSpec.m in Sources */, 162E837D1A9BDE8B00906325 /* SDLEmergencyEventSpec.m in Sources */, @@ -7348,6 +7395,7 @@ 1EE8C4461F3837D200FDC2CF /* SDLModuleDataSpec.m in Sources */, EEA41D45210BA8CF0006CB6E /* TestTCPServer.m in Sources */, 1E89B0DE2031636000A47992 /* SDLSeatControlDataSpec.m in Sources */, + 88FF4E7C2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m in Sources */, 8831FA3D220207DA00B8FFB7 /* SDLServiceUpdateReasonSpec.m in Sources */, 162E831A1A9BDE8B00906325 /* SDLOnLockScreenStatusSpec.m in Sources */, 162E83431A9BDE8B00906325 /* SDLSyncPDataSpec.m in Sources */, diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec index 8c4c289c8..34bf96d2c 100644 --- a/SmartDeviceLink.podspec +++ b/SmartDeviceLink.podspec @@ -275,6 +275,7 @@ sdefault.public_header_files = [ 'SmartDeviceLink/SDLRPCNotification.h', 'SmartDeviceLink/SDLRPCNotificationNotification.h', 'SmartDeviceLink/SDLRPCRequest.h', +'SmartDeviceLink/SDLRPCRequestNotification.h', 'SmartDeviceLink/SDLRPCResponse.h', 'SmartDeviceLink/SDLRPCResponseNotification.h', 'SmartDeviceLink/SDLRPCStruct.h', diff --git a/SmartDeviceLink/Requests/SDLRPCRequestNotification.h b/SmartDeviceLink/Requests/SDLRPCRequestNotification.h new file mode 100644 index 000000000..e78cd2981 --- /dev/null +++ b/SmartDeviceLink/Requests/SDLRPCRequestNotification.h @@ -0,0 +1,51 @@ +// +// SDLRPCRequestNotification.h +// SmartDeviceLink +// +// Created by Nicole on 2/14/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> + +@class SDLRPCRequest; + +NS_ASSUME_NONNULL_BEGIN + +/** + * A NSNotification object that makes retrieving internal SDLRPCRequest data easier + */ +@interface SDLRPCRequestNotification : NSNotification + +/** + * The request to be included in the userinfo dictionary + */ +@property (copy, nonatomic, readonly) __kindof SDLRPCRequest *request; + +/** + * Create an NSNotification object containing an SDLRPCRequest + * + * @param name The NSNotification name + * @param object The NSNotification object + * @param request The SDLRPCRequest payload + * @return The NSNotification + */ +- (instancetype)initWithName:(NSString *)name object:(nullable id)object rpcRequest:(__kindof SDLRPCRequest *)request; + +/** + * Returns whether or not the containing response is equal to a class, not including subclasses. + * + * @param aClass the class you are questioning + */ +- (BOOL)isRequestMemberOfClass:(Class)aClass; + +/** + * Returns whether or not the containing response is a kind of class, including subclasses. + * + * @param aClass the class you are questioning + */ +- (BOOL)isRequestKindOfClass:(Class)aClass; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/Requests/SDLRPCRequestNotification.m b/SmartDeviceLink/Requests/SDLRPCRequestNotification.m new file mode 100644 index 000000000..4ac6250c6 --- /dev/null +++ b/SmartDeviceLink/Requests/SDLRPCRequestNotification.m @@ -0,0 +1,49 @@ +// +// SDLRPCRequestNotification.m +// SmartDeviceLink +// +// Created by Nicole on 2/14/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import "SDLRPCRequestNotification.h" + +#import "SDLNotificationConstants.h" +#import "SDLRPCRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SDLRPCRequestNotification + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wimplicit-atomic-properties" +@synthesize name = _name; +@synthesize object = _object; +@synthesize userInfo = _userInfo; +#pragma clang diagnostic pop + +- (instancetype)initWithName:(NSString *)name object:(nullable id)object rpcRequest:(__kindof SDLRPCRequest *)request { + _name = name; + _object = object; + _userInfo = @{SDLNotificationUserInfoObject: request}; + + return self; +} + +- (__kindof SDLRPCRequest *)request { + return _userInfo[SDLNotificationUserInfoObject]; +} + +- (BOOL)isRequestMemberOfClass:(Class)aClass { + NSAssert([self.request isMemberOfClass:aClass], @"A notification was sent with an unanticipated object"); + return [self.request isMemberOfClass:aClass]; +} + +- (BOOL)isRequestKindOfClass:(Class)aClass { + NSAssert([self.request isKindOfClass:aClass], @"A notification was sent with an unanticipated object"); + return [self.request isKindOfClass:aClass]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLAppServiceData.h b/SmartDeviceLink/SDLAppServiceData.h index 07581e0ce..287c388dd 100644 --- a/SmartDeviceLink/SDLAppServiceData.h +++ b/SmartDeviceLink/SDLAppServiceData.h @@ -20,6 +20,17 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLAppServiceData : SDLRPCStruct /** + * Convenience init. + * + * @param serviceType The type of service that is to be offered by this app. + * @param serviceId A unique ID tied to this specific service record. + * @param mediaServiceData The media service data + * @param weatherServiceData The weather service data + * @return A SDLAppServiceData object + */ +- (instancetype)initWithServiceType:(NSString *)serviceType serviceId:(NSString *)serviceId mediaServiceData:(nullable SDLMediaServiceData *)mediaServiceData weatherServiceData:(nullable SDLWeatherServiceData *)weatherServiceData; + +/** * The type of service that is to be offered by this app. See AppServiceType. * * String, See `SDLAppServiceType`, Required diff --git a/SmartDeviceLink/SDLAppServiceData.m b/SmartDeviceLink/SDLAppServiceData.m index a4ad15460..a247dc988 100644 --- a/SmartDeviceLink/SDLAppServiceData.m +++ b/SmartDeviceLink/SDLAppServiceData.m @@ -17,6 +17,20 @@ NS_ASSUME_NONNULL_BEGIN @implementation SDLAppServiceData +- (instancetype)initWithServiceType:(NSString *)serviceType serviceId:(NSString *)serviceId mediaServiceData:(nullable SDLMediaServiceData *)mediaServiceData weatherServiceData:(nullable SDLWeatherServiceData *)weatherServiceData { + self = [self init]; + if (!self) { + return nil; + } + + self.serviceType = serviceType; + self.serviceId = serviceId; + self.mediaServiceData = mediaServiceData; + self.weatherServiceData = weatherServiceData; + + return self; +} + - (void)setServiceType:(NSString *)serviceType { [store sdl_setObject:serviceType forName:SDLNameServiceType]; } diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m index 5c67e3e8a..44dc938d5 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m @@ -90,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)sdl_sendRequest:(SDLRPCRequest *)request { __weak typeof(self) weakSelf = self; - [self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { + [self.connectionManager sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { __strong typeof(self) strongSelf = weakSelf; if (strongSelf.isCancelled) { diff --git a/SmartDeviceLink/SDLConnectionManagerType.h b/SmartDeviceLink/SDLConnectionManagerType.h index f7052f67d..9ae4eec06 100644 --- a/SmartDeviceLink/SDLConnectionManagerType.h +++ b/SmartDeviceLink/SDLConnectionManagerType.h @@ -10,6 +10,7 @@ #import <Foundation/Foundation.h> @class SDLRPCRequest; +@class SDLRPCMessage; @class SDLRegisterAppInterfaceResponse; @@ -26,15 +27,29 @@ NS_ASSUME_NONNULL_BEGIN - (void)sendConnectionManagerRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; /** - Send an RPC without bypassing the block on RPC sends before managers complete setup. - - @param request The RPC request to be sent to the remote head unit. - @param handler A completion block called when the response is received. + * Sends an RPC of type `SDLRPCRequest` without bypassing the block on RPC sends before managers complete setup. + * + * @param request The RPC request to be sent to the remote head unit. + * @param handler A completion block called when the response is received. */ -- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; +- (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler; +/** + * Sends an array of RPCs of type `Request` asynchronously. The requests are sent without bypassing the block on RPC sends before managers complete setup. + * + * @param requests An array of RPCs of type `Request` + * @param progressHandler The progress handler is called as each request gets a response from Core. + * @param completionHandler The completion handler is called when all requests have a response from Core. + */ - (void)sendRequests:(NSArray<SDLRPCRequest *> *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; +/** + * Sends an array of RPCs of type `Request` sequentially. The requests are sent without bypassing the block on RPC sends before managers complete setup. + * + * @param requests An array of RPCs of type `Request` + * @param progressHandler The progress handler is called as each request gets a response from Core. + * @param completionHandler The completion handler is called when all requests have a response from Core. + */ - (void)sendSequentialRequests:(NSArray<SDLRPCRequest *> *)requests progressHandler:(nullable SDLMultipleSequentialRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; @end diff --git a/SmartDeviceLink/SDLGetAppServiceDataResponse.h b/SmartDeviceLink/SDLGetAppServiceDataResponse.h index 6057ed0c8..b5e47e104 100644 --- a/SmartDeviceLink/SDLGetAppServiceDataResponse.h +++ b/SmartDeviceLink/SDLGetAppServiceDataResponse.h @@ -17,6 +17,14 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLGetAppServiceDataResponse : SDLRPCResponse /** + * Convenience init. + * + * @param serviceData Contains all the current data of the app service + * @return A SDLGetAppServiceDataResponse object + */ +- (instancetype)initWithAppServiceData:(SDLAppServiceData *)serviceData; + +/** * Contains all the current data of the app service. * * SDLAppServiceData, Required diff --git a/SmartDeviceLink/SDLGetAppServiceDataResponse.m b/SmartDeviceLink/SDLGetAppServiceDataResponse.m index e62c6e340..ea94c23eb 100644 --- a/SmartDeviceLink/SDLGetAppServiceDataResponse.m +++ b/SmartDeviceLink/SDLGetAppServiceDataResponse.m @@ -20,6 +20,17 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (instancetype)initWithAppServiceData:(SDLAppServiceData *)serviceData { + self = [self init]; + if (!self) { + return nil; + } + + self.serviceData = serviceData; + + return self; +} + - (void)setServiceData:(SDLAppServiceData *)serviceData { [parameters sdl_setObject:serviceData forName:SDLNameServiceData]; } diff --git a/SmartDeviceLink/SDLLifecycleManager.h b/SmartDeviceLink/SDLLifecycleManager.h index 594dccba3..239e1a370 100644 --- a/SmartDeviceLink/SDLLifecycleManager.h +++ b/SmartDeviceLink/SDLLifecycleManager.h @@ -26,6 +26,7 @@ @class SDLPutFile; @class SDLRegisterAppInterfaceResponse; @class SDLResponseDispatcher; +@class SDLRPCMessage; @class SDLRPCNotification; @class SDLRPCRequest; @class SDLRPCResponse; @@ -121,7 +122,7 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); * * @param request The RPC request to send */ -- (void)sendRequest:(SDLRPCRequest *)request; +- (void)sendRequest:(__kindof SDLRPCMessage *)request; /** * Send an RPC request and set a completion handler that will be called with the response when the response returns. @@ -129,7 +130,7 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); * @param request The RPC request to send * @param handler The handler that will be called when the response returns */ -- (void)sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; +- (void)sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler; /** Send all of the requests given as quickly as possible, but in order. Call the completionHandler after all requests have either failed or given a response. diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 5436d8945..1a5070154 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -43,6 +43,7 @@ #import "SDLRegisterAppInterface.h" #import "SDLRegisterAppInterfaceResponse.h" #import "SDLResponseDispatcher.h" +#import "SDLRPCResponseOperation.h" #import "SDLResult.h" #import "SDLScreenManager.h" #import "SDLSecondaryTransportManager.h" @@ -522,11 +523,23 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; #pragma mark Sending Requests -- (void)sendRequest:(SDLRPCRequest *)request { - [self sendRequest:request withResponseHandler:nil]; +- (void)sendRequest:(__kindof SDLRPCMessage *)request { + if ([request isKindOfClass:SDLRPCRequest.class]) { + SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; + [self sendRequest:requestRPC withResponseHandler:nil]; + } else if ([request isKindOfClass:SDLRPCResponse.class] || [request isKindOfClass:SDLRPCNotification.class]) { + [self sdl_sendRPC:request]; + } else { + NSAssert(false, @"The request should be of type `Request`, `Response` or `Notification"); + } +} + +- (void)sdl_sendRPC:(__kindof SDLRPCMessage *)rpc { + SDLRPCResponseOperation *op = [[SDLRPCResponseOperation alloc] initWithConnectionManager:self rpc:rpc]; + [self.rpcOperationQueue addOperation:op]; } -- (void)sendRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { SDLAsynchronousRPCRequestOperation *op = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:self request:request responseHandler:handler]; [self.rpcOperationQueue addOperation:op]; } @@ -551,10 +564,10 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; [self.rpcOperationQueue addOperation:op]; } -- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { if (![self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) { SDLLogW(@"Manager not ready, message not sent (%@)", request); - if (handler) { + if (handler && [request isKindOfClass:SDLRPCRequest.class]) { dispatch_async(dispatch_get_main_queue(), ^{ handler(request, nil, [NSError sdl_lifecycle_notReadyError]); }); @@ -569,13 +582,13 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; } // Managers need to avoid state checking. Part of <SDLConnectionManagerType>. -- (void)sendConnectionManagerRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendConnectionManagerRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { dispatch_async(_lifecycleQueue, ^{ [self sdl_sendRequest:request withResponseHandler:handler]; }); } -- (void)sdl_sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { // We will allow things to be sent in a "SDLLifecycleStateConnected" state in the private method, but block it in the public method sendRequest:withCompletionHandler: so that the lifecycle manager can complete its setup without being bothered by developer error NSParameterAssert(request != nil); @@ -591,12 +604,18 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; return; } - // Add a correlation ID to the request - NSNumber *corrID = [self sdl_getNextCorrelationId]; - request.correlationID = corrID; - - [self.responseDispatcher storeRequest:request handler:handler]; - [self.proxy sendRPC:request]; + if ([request isKindOfClass:SDLRPCRequest.class]) { + // Generate and add a correlation ID to the request. When a response for the request is returned from Core, it will have the same correlation ID + SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; + NSNumber *corrID = [self sdl_getNextCorrelationId]; + requestRPC.correlationID = corrID; + [self.responseDispatcher storeRequest:requestRPC handler:handler]; + [self.proxy sendRPC:requestRPC]; + } else if ([request isKindOfClass:SDLRPCResponse.class] || [request isKindOfClass:SDLRPCNotification.class]) { + [self.proxy sendRPC:request]; + } else { + SDLLogE(@"Attempting to send an RPC with unknown type, %@. The request should be of type request, response or notification. Returning...", request.class); + } } diff --git a/SmartDeviceLink/SDLManager.h b/SmartDeviceLink/SDLManager.h index b984a58a5..b0a0fbe08 100644 --- a/SmartDeviceLink/SDLManager.h +++ b/SmartDeviceLink/SDLManager.h @@ -15,6 +15,7 @@ @class SDLProxy; @class SDLPutFile; @class SDLRegisterAppInterfaceResponse; +@class SDLRPCMessage; @class SDLRPCNotification; @class SDLRPCRequest; @class SDLRPCResponse; @@ -133,6 +134,13 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); #pragma mark Manually Send RPC Requests /** + * Send an RPC of type `Response`, `Notification` or `Request`. Responses and notifications sent to Core do not a response back from Core. Each request sent to Core does get a response, so if you need the response and/or error, call `sendRequest:withResponseHandler:` instead. + * + * @param rpc An RPC of type `SDLRPCResponse`, `SDLRPCNotification` or `SDLRPCRequest` + */ +- (void)sendRPC:(__kindof SDLRPCMessage *)rpc; + +/** * Send an RPC request and don't bother with the response or error. If you need the response or error, call sendRequest:withCompletionHandler: instead. * * @param request The RPC request to send diff --git a/SmartDeviceLink/SDLManager.m b/SmartDeviceLink/SDLManager.m index fa7c9e8e0..a485efdcc 100644 --- a/SmartDeviceLink/SDLManager.m +++ b/SmartDeviceLink/SDLManager.m @@ -119,12 +119,16 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark SDLConnectionManager Protocol +- (void)sendRPC:(__kindof SDLRPCMessage *)rpc { + [self.lifecycleManager sendRequest:rpc]; +} + - (void)sendRequest:(SDLRPCRequest *)request { [self sendRequest:request withResponseHandler:nil]; } - (void)sendRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { - [self.lifecycleManager sendRequest:request withResponseHandler:handler]; + [self.lifecycleManager sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:handler]; } - (void)sendRequests:(NSArray<SDLRPCRequest *> *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { diff --git a/SmartDeviceLink/SDLMediaServiceData.h b/SmartDeviceLink/SDLMediaServiceData.h index 6df77c304..8b44a4aa9 100644 --- a/SmartDeviceLink/SDLMediaServiceData.h +++ b/SmartDeviceLink/SDLMediaServiceData.h @@ -19,6 +19,25 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLMediaServiceData : SDLRPCStruct /** + * Convenience init + * + * @param mediaType The type of the currently playing or paused track + * @param mediaTitle The name of the current playing media + * @param mediaArtist The name of the current media artist + * @param mediaAlbum The name of the current media album + * @param playlistName The name of the playlist + * @param isExplicit Whether or not the content currently playing contains explicit content + * @param trackPlaybackProgress The current progress of the track + * @param trackPlaybackDuration The total duration of the track + * @param queuePlaybackProgess The current progress of the playback queue in seconds + * @param queuePlaybackDuration The total duration of the playback queue in seconds + * @param queueCurrentTrackNumber The current number (1 based) of the track in the playback queue + * @param queueTotalTrackCount The total number of tracks in the playback queue + * @return A SDLMediaServiceData object + */ +- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgess:(UInt32)queuePlaybackProgess queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount; + +/** * The type of the currently playing or paused track. * * SDLMediaType, Optional diff --git a/SmartDeviceLink/SDLMediaServiceData.m b/SmartDeviceLink/SDLMediaServiceData.m index 0a1ef3679..9df7d22be 100644 --- a/SmartDeviceLink/SDLMediaServiceData.m +++ b/SmartDeviceLink/SDLMediaServiceData.m @@ -15,6 +15,28 @@ NS_ASSUME_NONNULL_BEGIN @implementation SDLMediaServiceData +- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgess:(UInt32)queuePlaybackProgess queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount { + self = [self init]; + if (!self) { + return nil; + } + + self.mediaType = mediaType; + self.mediaTitle = mediaTitle; + self.mediaArtist = mediaArtist; + self.mediaAlbum = mediaAlbum; + self.playlistName = playlistName; + self.isExplicit = @(isExplicit); + self.trackPlaybackProgress = @(trackPlaybackProgress); + self.trackPlaybackDuration = @(trackPlaybackDuration); + self.queuePlaybackProgess = @(queuePlaybackProgess); + self.queuePlaybackDuration = @(queuePlaybackDuration); + self.queueCurrentTrackNumber = @(queueCurrentTrackNumber); + self.queueTotalTrackCount = @(queueTotalTrackCount); + + return self; +} + - (void)setMediaType:(nullable SDLMediaType)mediaType { [store sdl_setObject:mediaType forName:SDLNameMediaType]; } diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h index 36be5c240..9c3bf024e 100644 --- a/SmartDeviceLink/SDLNotificationConstants.h +++ b/SmartDeviceLink/SDLNotificationConstants.h @@ -171,6 +171,13 @@ extern SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataResponse; extern SDLNotificationName const SDLDidReceiveUnsubscribeWaypointsResponse; /** + * NSNotification names associated with specific RPC requests. + */ +#pragma mark - RPC requests +extern SDLNotificationName const SDLDidReceivePerformAppServiceInteractionRequest; +extern SDLNotificationName const SDLDidReceiveGetAppServiceDataRequest; + +/** * NSNotification names associated with specific RPC notifications. */ #pragma mark - RPC Notifications @@ -206,14 +213,6 @@ extern SDLNotificationName const SDLDidReceiveWaypointNotification; */ + (NSArray<SDLNotificationName> *)allResponseNames; - -/** - All of the possible SDL RPC Request notification names - - @return All request notification names - */ -+ (NSArray<SDLNotificationName> *)allRequestNames; - /** All of the possible SDL Button event notification names diff --git a/SmartDeviceLink/SDLNotificationConstants.m b/SmartDeviceLink/SDLNotificationConstants.m index 247e17fb0..fb7a43cca 100644 --- a/SmartDeviceLink/SDLNotificationConstants.m +++ b/SmartDeviceLink/SDLNotificationConstants.m @@ -78,6 +78,10 @@ SDLNotificationName const SDLDidReceiveUnsubscribeButtonResponse = @"com.sdl.res SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataResponse = @"com.sdl.response.unsubscribeVehicleData"; SDLNotificationName const SDLDidReceiveUnsubscribeWaypointsResponse = @"com.sdl.response.unsubscribeWaypoints"; +#pragma mark - RPC Requests +SDLNotificationName const SDLDidReceivePerformAppServiceInteractionRequest = @"com.sdl.request.performAppServiceInteraction"; +SDLNotificationName const SDLDidReceiveGetAppServiceDataRequest = @"com.sdl.request.getAppServiceData"; + #pragma mark - RPC Notifications SDLNotificationName const SDLDidChangeDriverDistractionStateNotification = @"com.sdl.notification.changeDriverDistractionStateNotification"; SDLNotificationName const SDLDidChangeHMIStatusNotification = @"com.sdl.notification.changeHMIStatus"; @@ -160,10 +164,6 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica SDLDidReceiveUnsubscribeWaypointsResponse]; } -+ (NSArray<SDLNotificationName> *)allRequestNames { - return @[]; -} - + (NSArray<SDLNotificationName> *)allButtonEventNotifications { return @[SDLDidReceiveButtonEventNotification, SDLDidReceiveButtonPressNotification]; diff --git a/SmartDeviceLink/SDLNotificationDispatcher.h b/SmartDeviceLink/SDLNotificationDispatcher.h index ba5089a25..f820ddc91 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.h +++ b/SmartDeviceLink/SDLNotificationDispatcher.h @@ -10,6 +10,7 @@ #import "SDLProxyListener.h" +@class SDLRPCRequest; @class SDLRPCResponse; @class SDLRPCNotification; @@ -22,13 +23,35 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLNotificationDispatcher : NSObject <SDLProxyListener> /** - * Post a notification with a specified name and object. + * Posts a notification with a specified name and object. * - * @param name The name of the notification to be dispatched. - * @param info The object to be send along in the `userInfo` dictionary. + * @param name The name of the notification to be dispatched. + * @param info The notification object to be sent in the `userInfo` dictionary. */ - (void)postNotificationName:(NSString *)name infoObject:(nullable id)info; + +/** + * Posts a request from Core with a specified name and request object + * + * @param name The name of the request to be dispatched + * @param request The request object to be sent in the `userInfo` dictionary + */ +- (void)postRPCRequestNotification:(NSString *)name request:(__kindof SDLRPCRequest *)request; + +/** + * Posts a response from Core with a specified name and response object + * + * @param name The name of the response to be dispatched + * @param response The response object to be sent in the `userInfo` dictionary + */ - (void)postRPCResponseNotification:(NSString *)name response:(__kindof SDLRPCResponse *)response; + +/** + * Posts a notification from Core with a specified name and notification object + * + * @param name The name of the notification to be dispatched + * @param rpcNotification The notification object to be sent in the `userInfo` dictionary + */ - (void)postRPCNotificationNotification:(NSString *)name notification:(__kindof SDLRPCNotification *)rpcNotification; @end diff --git a/SmartDeviceLink/SDLNotificationDispatcher.m b/SmartDeviceLink/SDLNotificationDispatcher.m index 8ca899476..aff64f93f 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.m +++ b/SmartDeviceLink/SDLNotificationDispatcher.m @@ -12,6 +12,7 @@ #import "SDLNotificationConstants.h" #import "SDLRPCNotification.h" #import "SDLRPCNotificationNotification.h" +#import "SDLRPCRequestNotification.h" #import "SDLRPCResponseNotification.h" NS_ASSUME_NONNULL_BEGIN @@ -35,6 +36,13 @@ NS_ASSUME_NONNULL_BEGIN [[NSNotificationCenter defaultCenter] postNotificationName:name object:self userInfo:userInfo]; } +- (void)postRPCRequestNotification:(NSString *)name request:(__kindof SDLRPCRequest *)request { + SDLRPCRequestNotification *notification = [[SDLRPCRequestNotification alloc] initWithName:name object:self rpcRequest:request]; + + // Runs on `com.sdl.rpcProcessingQueue` + [[NSNotificationCenter defaultCenter] postNotification:notification]; +} + - (void)postRPCResponseNotification:(NSString *)name response:(__kindof SDLRPCResponse *)response { SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:name object:self rpcResponse:response]; @@ -149,6 +157,10 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceiveGenericResponse response:response]; } +- (void)onGetAppServiceData:(SDLGetAppServiceData *)request { + [self postRPCRequestNotification:SDLDidReceiveGetAppServiceDataRequest request:request]; +} + - (void)onGetAppServiceDataResponse:(SDLGetAppServiceDataResponse *)response { [self postRPCResponseNotification:SDLDidReceiveGetAppServiceDataResponse response:response]; } @@ -181,6 +193,10 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceiveListFilesResponse response:response]; } +- (void)onPerformAppServiceInteraction:(SDLPerformAppServiceInteraction *)request { + [self postRPCRequestNotification:SDLDidReceivePerformAppServiceInteractionRequest request:request]; +} + - (void)onPerformAppServiceInteractionResponse:(SDLPerformAppServiceInteractionResponse *)response { [self postRPCResponseNotification:SDLDidReceivePerformAppServiceInteractionResponse response:response]; } @@ -193,7 +209,7 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceivePerformInteractionResponse response:response]; } -- (void)onPublishAppService:(SDLPublishAppService *)response { +- (void)onPublishAppServiceResponse:(SDLPublishAppServiceResponse *)response { [self postRPCResponseNotification:SDLDidReceivePublishAppServiceResponse response:response]; } diff --git a/SmartDeviceLink/SDLOnAppServiceData.h b/SmartDeviceLink/SDLOnAppServiceData.h index d131b8749..5d2fd2d0d 100644 --- a/SmartDeviceLink/SDLOnAppServiceData.h +++ b/SmartDeviceLink/SDLOnAppServiceData.h @@ -7,7 +7,8 @@ // #import "SDLRPCNotification.h" -#import "SDLAppServiceData.h" + +@class SDLAppServiceData; NS_ASSUME_NONNULL_BEGIN @@ -17,6 +18,14 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLOnAppServiceData : SDLRPCNotification /** + * Convenience init + * + * @param serviceData The updated app service data + * @return A SDLOnAppServiceData object + */ +- (instancetype)initWithServiceData:(SDLAppServiceData *)serviceData; + +/** * The updated app service data. * * SDLAppServiceData, Required diff --git a/SmartDeviceLink/SDLOnAppServiceData.m b/SmartDeviceLink/SDLOnAppServiceData.m index b58c78a7c..aac381039 100644 --- a/SmartDeviceLink/SDLOnAppServiceData.m +++ b/SmartDeviceLink/SDLOnAppServiceData.m @@ -10,6 +10,8 @@ #import "NSMutableDictionary+Store.h" #import "SDLNames.h" +#import "SDLAppServiceData.h" + NS_ASSUME_NONNULL_BEGIN @implementation SDLOnAppServiceData @@ -20,6 +22,17 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (instancetype)initWithServiceData:(SDLAppServiceData *)serviceData { + self = [self init]; + if (!self) { + return nil; + } + + self.serviceData = serviceData; + + return self; +} + - (void)setServiceData:(SDLAppServiceData *)serviceData { [parameters sdl_setObject:serviceData forName:SDLNameServiceData]; } diff --git a/SmartDeviceLink/SDLProxyListener.h b/SmartDeviceLink/SDLProxyListener.h index 45d961638..493f59bd4 100644 --- a/SmartDeviceLink/SDLProxyListener.h +++ b/SmartDeviceLink/SDLProxyListener.h @@ -19,6 +19,7 @@ @class SDLEncodedSyncPDataResponse; @class SDLEndAudioPassThruResponse; @class SDLGenericResponse; +@class SDLGetAppServiceData; @class SDLGetAppServiceDataResponse; @class SDLGetDTCsResponse; @class SDLGetFileResponse; @@ -50,10 +51,11 @@ @class SDLOnTouchEvent; @class SDLOnVehicleData; @class SDLOnWayPointChange; +@class SDLPerformAppServiceInteraction; @class SDLPerformAppServiceInteractionResponse; @class SDLPerformAudioPassThruResponse; @class SDLPerformInteractionResponse; -@class SDLPublishAppService; +@class SDLPublishAppServiceResponse; @class SDLPutFileResponse; @class SDLReadDIDResponse; @class SDLRegisterAppInterfaceResponse; @@ -230,6 +232,13 @@ NS_ASSUME_NONNULL_BEGIN - (void)onGenericResponse:(SDLGenericResponse *)response; /** + * Called when a Get App Service Data Request is received from Core + * + * @param request A SDLGetAppServiceData object + */ +- (void)onGetAppServiceData:(SDLGetAppServiceData *)request; + +/** * Called when a Get App Service Data Response is received from Core * * @param response A SDLGetAppServiceDataResponse object @@ -433,6 +442,13 @@ NS_ASSUME_NONNULL_BEGIN - (void)onOnWayPointChange:(SDLOnWayPointChange *)notification; /** + * Called when a Perform App Service Interaction Request is received from Core + * + * @param request A SDLPerformAppServiceInteraction object + */ +- (void)onPerformAppServiceInteraction:(SDLPerformAppServiceInteraction *)request; + +/** * Called when a Perform App Service Interaction Response is received from Core * * @param response A SDLPerformAppServiceInteractionResponse object @@ -458,7 +474,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param response A SDLPublishAppService object */ -- (void)onPublishAppService:(SDLPublishAppService *)response; +- (void)onPublishAppServiceResponse:(SDLPublishAppServiceResponse *)response; /** * Called when a Put File Response is received from Core diff --git a/SmartDeviceLink/SDLRPCResponseNotification.h b/SmartDeviceLink/SDLRPCResponseNotification.h index 8d77dd767..4434f2a04 100644 --- a/SmartDeviceLink/SDLRPCResponseNotification.h +++ b/SmartDeviceLink/SDLRPCResponseNotification.h @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLRPCResponseNotification : NSNotification /** - * The response within the userinfo dictionary + * The response to be included within the userinfo dictionary */ @property (copy, nonatomic, readonly) __kindof SDLRPCResponse *response; diff --git a/SmartDeviceLink/SDLRPCResponseOperation.h b/SmartDeviceLink/SDLRPCResponseOperation.h new file mode 100644 index 000000000..ffb56e1ad --- /dev/null +++ b/SmartDeviceLink/SDLRPCResponseOperation.h @@ -0,0 +1,26 @@ +// +// SDLRPCResponseOperation.h +// SmartDeviceLink +// +// Created by Nicole on 2/20/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import <UIKit/UIKit.h> + +#import "SDLAsynchronousOperation.h" +#import "SDLLifecycleManager.h" + +@protocol SDLConnectionManagerType; + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLRPCResponseOperation : SDLAsynchronousOperation + +@property (copy, nonatomic) __kindof SDLRPCMessage *rpc; + +- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager rpc:(__kindof SDLRPCMessage *)rpc; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLRPCResponseOperation.m b/SmartDeviceLink/SDLRPCResponseOperation.m new file mode 100644 index 000000000..6277b693c --- /dev/null +++ b/SmartDeviceLink/SDLRPCResponseOperation.m @@ -0,0 +1,88 @@ +// +// SDLRPCResponseOperation.m +// SmartDeviceLink +// +// Created by Nicole on 2/20/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import "SDLRPCResponseOperation.h" + +#import "SDLConnectionManagerType.h" +#import "SDLError.h" +#import "SDLRPCMessage.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLRPCResponseOperation () + +@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager; +@property (strong, nonatomic) NSUUID *operationId; + +@end + +@implementation SDLRPCResponseOperation { + BOOL executing; + BOOL finished; +} + +- (instancetype)init { + self = [super init]; + if (!self) { return nil; } + + executing = NO; + finished = NO; + + _operationId = [NSUUID UUID]; + + return self; +} + +- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager rpc:(__kindof SDLRPCMessage *)rpc { + self = [self init]; + + _rpc = rpc; + _connectionManager = connectionManager; + + return self; +} + +- (void)start { + [super start]; + [self sdl_sendRPC:self.rpc]; +} + +- (void)sdl_sendRPC:(__kindof SDLRPCMessage *)rpc { + if (self.isCancelled) { + [self sdl_abortOperation]; + return; + } + + [self.connectionManager sendConnectionRequest:rpc withResponseHandler:nil]; + [self finishOperation]; +} + +- (void)sdl_abortOperation { + [self finishOperation]; +} + +#pragma mark - Property Overrides +- (nullable NSString *)name { + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; +} + +- (NSOperationQueuePriority)queuePriority { + return NSOperationQueuePriorityNormal; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@", self.name]; +} + +- (NSString *)debugDescription { + return [NSString stringWithFormat:@"%@, request type=%@", self.name, self.rpc.class]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLSequentialRPCRequestOperation.m b/SmartDeviceLink/SDLSequentialRPCRequestOperation.m index 142812d40..35c7638a1 100644 --- a/SmartDeviceLink/SDLSequentialRPCRequestOperation.m +++ b/SmartDeviceLink/SDLSequentialRPCRequestOperation.m @@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN // Send the next request SDLRPCRequest *request = self.requests[self.currentRequestIndex]; - [self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { + [self.connectionManager sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { self.requestsComplete++; // If this request failed and no request has yet failed, set our internal request failed to YES diff --git a/SmartDeviceLink/SDLWeatherServiceData.h b/SmartDeviceLink/SDLWeatherServiceData.h index cb09c5f24..f9b953816 100644 --- a/SmartDeviceLink/SDLWeatherServiceData.h +++ b/SmartDeviceLink/SDLWeatherServiceData.h @@ -20,6 +20,19 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLWeatherServiceData : SDLRPCStruct /** + * Convenience init. + * + * @param location The location + * @param currentForecast The current forecast + * @param minuteForecast A minute-by-minute array of forecasts + * @param hourlyForecast An hour-by-hour array of forecasts + * @param multidayForecast A day-by-day array of forecasts + * @param alerts An array of weather alerts + * @return A SDLWeatherServiceData object + */ +- (instancetype)initWithLocation:(SDLLocationDetails *)location currentForecast:(nullable SDLWeatherData *)currentForecast minuteForecast:(nullable NSArray<SDLWeatherData *> *)minuteForecast hourlyForecast:(NSArray<SDLWeatherData *> *)hourlyForecast multidayForecast:(nullable NSArray<SDLWeatherData *> *)multidayForecast alerts:(NSArray<SDLWeatherAlert *> *)alerts; + +/** * The location. * * SDLLocationDetails, Required @@ -48,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, strong, nonatomic) NSArray<SDLWeatherData *> *hourlyForecast; /** - * An day-by-day array of forecasts. + * A day-by-day array of forecasts. * * Array of SDLWeatherData, Optional, minsize="1" maxsize="30" */ diff --git a/SmartDeviceLink/SDLWeatherServiceData.m b/SmartDeviceLink/SDLWeatherServiceData.m index 785a7f990..2932c1688 100644 --- a/SmartDeviceLink/SDLWeatherServiceData.m +++ b/SmartDeviceLink/SDLWeatherServiceData.m @@ -15,6 +15,22 @@ NS_ASSUME_NONNULL_BEGIN @implementation SDLWeatherServiceData +- (instancetype)initWithLocation:(SDLLocationDetails *)location currentForecast:(nullable SDLWeatherData *)currentForecast minuteForecast:(nullable NSArray<SDLWeatherData *> *)minuteForecast hourlyForecast:(NSArray<SDLWeatherData *> *)hourlyForecast multidayForecast:(nullable NSArray<SDLWeatherData *> *)multidayForecast alerts:(NSArray<SDLWeatherAlert *> *)alerts { + self = [self init]; + if (!self) { + return nil; + } + + self.location = location; + self.currentForecast = currentForecast; + self.minuteForecast = minuteForecast; + self.hourlyForecast = hourlyForecast; + self.multidayForecast = multidayForecast; + self.alerts = alerts; + + return self; +} + - (void)setLocation:(SDLLocationDetails *)location { [store sdl_setObject:location forName:SDLNameLocation]; } diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h index 0b29f01cd..6958a961e 100644 --- a/SmartDeviceLink/SmartDeviceLink.h +++ b/SmartDeviceLink/SmartDeviceLink.h @@ -413,6 +413,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; // Notifications #import "SDLRPCNotificationNotification.h" #import "SDLRPCResponseNotification.h" +#import "SDLRPCRequestNotification.h" // Logger #import "SDLLogConstants.h" diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index 49892f366..ad703881d 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -4,6 +4,7 @@ #import "SDLLifecycleManager.h" +#import "SDLAppServiceData.h" #import "SDLConfiguration.h" #import "SDLConnectionManagerType.h" #import "SDLError.h" @@ -16,8 +17,10 @@ #import "SDLLogConfiguration.h" #import "SDLManagerDelegate.h" #import "SDLNotificationDispatcher.h" +#import "SDLOnAppServiceData.h" #import "SDLOnHashChange.h" #import "SDLOnHMIStatus.h" +#import "SDLPerformAppServiceInteractionResponse.h" #import "SDLPermissionManager.h" #import "SDLProxy.h" #import "SDLProtocol.h" @@ -75,7 +78,7 @@ describe(@"a lifecycle manager", ^{ __block SDLConfiguration *testConfig = nil; __block id protocolMock = OCMClassMock([SDLProtocol class]); - __block id proxyMock = OCMClassMock([SDLProxy class]); + __block id proxyMock = OCMClassMock([SDLProxy class]);; __block id lockScreenManagerMock = OCMClassMock([SDLLockScreenManager class]); __block id fileManagerMock = OCMClassMock([SDLFileManager class]); __block id permissionManagerMock = OCMClassMock([SDLPermissionManager class]); @@ -128,6 +131,8 @@ describe(@"a lifecycle manager", ^{ expect(testManager.responseDispatcher).toNot(beNil()); expect(testManager.streamManager).toNot(beNil()); expect(testManager.systemCapabilityManager).toNot(beNil()); + expect(testManager.rpcOperationQueue).toNot(beNil()); + expect(testManager.rpcOperationQueue.maxConcurrentOperationCount).to(equal(3)); expect(@([testManager conformsToProtocol:@protocol(SDLConnectionManagerType)])).to(equal(@YES)); }); @@ -441,13 +446,44 @@ describe(@"a lifecycle manager", ^{ [testManager.lifecycleStateMachine setToState:SDLLifecycleStateReady fromOldState:nil callEnterTransition:NO]; }); - it(@"can send an RPC", ^{ + it(@"can send an RPC of type Request", ^{ SDLShow *testShow = [[SDLShow alloc] initWithMainField1:@"test" mainField2:nil alignment:nil]; [testManager sendRequest:testShow]; - OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:[SDLShow class]]]); + [NSThread sleepForTimeInterval:0.1]; + + OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:SDLShow.class]]); }); - + + it(@"can send an RPC of type Response", ^{ + SDLPerformAppServiceInteractionResponse *testResponse = [[SDLPerformAppServiceInteractionResponse alloc] init]; + [testManager sendRequest:testResponse]; + testResponse.correlationID = @(2); + testResponse.success = @(true); + testResponse.resultCode = SDLResultSuccess; + testResponse.info = @"testResponse info"; + + [NSThread sleepForTimeInterval:0.1]; + + OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:SDLPerformAppServiceInteractionResponse.class]]); + }); + + it(@"can send an RPC of type Notification", ^{ + SDLOnAppServiceData *testNotification = [[SDLOnAppServiceData alloc] initWithServiceData:[[SDLAppServiceData alloc] init]]; + [testManager sendRequest:testNotification]; + + [NSThread sleepForTimeInterval:0.1]; + + OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:SDLOnAppServiceData.class]]); + }); + + it(@"should throw an exception if the RPC is not of type `Request`, `Response` or `Notification`", ^{ + SDLRPCMessage *testMessage = [[SDLRPCMessage alloc] init]; + expectAction(^{ + [testManager sendRequest:testMessage]; + }).to(raiseException()); + }); + describe(@"stopping the manager", ^{ beforeEach(^{ [testManager stop]; diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLNotificationDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m index 63d691ee0..8464a481d 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLNotificationDispatcherSpec.m +++ b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m @@ -37,6 +37,7 @@ describe(@"a notification dispatcher", ^{ expect(@([testDispatcher respondsToSelector:@selector(onEndAudioPassThruResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onError:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGenericResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceData:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceDataResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetDTCsResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetFileResponse:)])).to(beTruthy()); @@ -62,10 +63,11 @@ describe(@"a notification dispatcher", ^{ expect(@([testDispatcher respondsToSelector:@selector(onOnTouchEvent:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onOnVehicleData:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onOnWayPointChange:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteraction:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteractionResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformAudioPassThruResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformInteractionResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPublishAppService:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPublishAppServiceResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPutFileResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onReadDIDResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onRegisterAppInterfaceResponse:)])).to(beTruthy()); @@ -96,7 +98,6 @@ describe(@"a notification dispatcher", ^{ describe(@"when told to post a notification", ^{ __block NSString *testNotificationName = nil; __block NSString *testUserInfo = nil; - __block NSNotification *returnNotification = nil; beforeEach(^{ diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLResponseDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m index 410d24386..410d24386 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLResponseDispatcherSpec.m +++ b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m diff --git a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m index 3ea76689f..6b68be0b9 100644 --- a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m @@ -9,6 +9,7 @@ #import <Quick/Quick.h> #import <Nimble/Nimble.h> +#import "SDLAppServiceData.h" #import "SDLOnAppServiceData.h" #import "SDLNames.h" @@ -40,6 +41,12 @@ describe(@"Getter/Setter Tests", ^{ expect(testNotification.serviceData).to(equal(testAppServiceData)); }); + it(@"Should get correctly when initialized with initWithServiceData:", ^{ + SDLOnAppServiceData *testNotification = [[SDLOnAppServiceData alloc] initWithServiceData:testAppServiceData]; + + expect(testNotification.serviceData).to(equal(testAppServiceData)); + }); + it(@"Should return nil if not set", ^{ SDLOnAppServiceData *testNotification = [[SDLOnAppServiceData alloc] init]; diff --git a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m index 41deb72d1..5f722514a 100644 --- a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m @@ -42,6 +42,12 @@ describe(@"Getter/Setter Tests", ^{ expect(testResponse.serviceData).to(equal(testAppServiceData)); }); + it(@"Should get correctly when initialized with initWithAppServiceData:", ^{ + SDLGetAppServiceDataResponse *testResponse = [[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:testAppServiceData]; + + expect(testResponse.serviceData).to(equal(testAppServiceData)); + }); + it(@"Should return nil if not set", ^{ SDLGetAppServiceDataResponse *testResponse = [[SDLGetAppServiceDataResponse alloc] init]; diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m index c9356b7a0..968190832 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m @@ -57,6 +57,15 @@ describe(@"Getter/Setter Tests", ^{ expect(testStruct.weatherServiceData).to(equal(testWeatherServiceData)); }); + it(@"Should get correctly when initialized with initWithServiceType:serviceId:mediaServiceData:weatherServiceData:", ^{ + SDLAppServiceData *testStruct = [[SDLAppServiceData alloc] initWithServiceType:testServiceType serviceId:testServiceId mediaServiceData:testMediaServiceData weatherServiceData:testWeatherServiceData]; + + expect(testStruct.serviceType).to(equal(testServiceType)); + expect(testStruct.serviceId).to(equal(testServiceId)); + expect(testStruct.mediaServiceData).to(equal(testMediaServiceData)); + expect(testStruct.weatherServiceData).to(equal(testWeatherServiceData)); + }); + it(@"Should return nil if not set", ^{ SDLAppServiceData *testStruct = [[SDLAppServiceData alloc] init]; diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m index 9530a179d..dc2731c47 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m @@ -97,6 +97,23 @@ describe(@"Getter/Setter Tests", ^{ expect(testStruct.queueTotalTrackCount).to(equal(testQueueTotalTrackCount)); }); + it(@"Should get correctly when initialized with initWithMediaType:mediaTitle:mediaArtist:mediaAlbum:playlistName:isExplicit:trackPlaybackProgress:trackPlaybackDuration:queuePlaybackProgess:queuePlaybackDuration:queueCurrentTrackNumber:queueTotalTrackCount:", ^{ + SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] initWithMediaType:testMediaType mediaTitle:testMediaTitle mediaArtist:testMediaArtist mediaAlbum:testMediaAlbum playlistName:testPlaylistName isExplicit:testIsExplicit trackPlaybackProgress:testTrackPlaybackProgress trackPlaybackDuration:testTrackPlaybackDuration queuePlaybackProgess:testQueuePlaybackProgress queuePlaybackDuration:testQueuePlaybackDuration queueCurrentTrackNumber:testQueueCurrentTrackNumber queueTotalTrackCount:testQueueTotalTrackCount]; + + expect(testStruct.mediaType).to(equal(testMediaType)); + expect(testStruct.mediaTitle).to(equal(testMediaTitle)); + expect(testStruct.mediaArtist).to(equal(testMediaArtist)); + expect(testStruct.mediaAlbum).to(equal(testMediaAlbum)); + expect(testStruct.playlistName).to(equal(testPlaylistName)); + expect(testStruct.isExplicit).to(equal(testIsExplicit)); + expect(testStruct.trackPlaybackProgress).to(equal(testTrackPlaybackProgress)); + expect(testStruct.trackPlaybackDuration).to(equal(testTrackPlaybackDuration)); + expect(testStruct.queuePlaybackProgess).to(equal(testQueuePlaybackProgress)); + expect(testStruct.queuePlaybackDuration).to(equal(testQueuePlaybackDuration)); + expect(testStruct.queueCurrentTrackNumber).to(equal(testQueueCurrentTrackNumber)); + expect(testStruct.queueTotalTrackCount).to(equal(testQueueTotalTrackCount)); + }); + it(@"Should return nil if not set", ^{ SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] init]; diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m index 7b896ca28..530b516de 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m @@ -76,6 +76,17 @@ describe(@"Getter/Setter Tests", ^{ expect(testStruct.alerts).to(equal(testAlerts)); }); + it(@"Should get correctly when initialized with initWithLocation:currentForecast:currentForecast minuteForecast:hourlyForecast:multidayForecast:alerts:", ^{ + SDLWeatherServiceData *testStruct = [[SDLWeatherServiceData alloc] initWithLocation:testLocation currentForecast:testCurrentForecast minuteForecast:testMinuteForecast hourlyForecast:testHourlyForecast multidayForecast:testMultidayForecast alerts:testAlerts]; + + expect(testStruct.location).to(equal(testLocation)); + expect(testStruct.currentForecast).to(equal(testCurrentForecast)); + expect(testStruct.minuteForecast).to(equal(testMinuteForecast)); + expect(testStruct.hourlyForecast).to(equal(testHourlyForecast)); + expect(testStruct.multidayForecast).to(equal(testMultidayForecast)); + expect(testStruct.alerts).to(equal(testAlerts)); + }); + it(@"Should return nil if not set", ^{ SDLWeatherServiceData *testStruct = [[SDLWeatherServiceData alloc] init]; diff --git a/SmartDeviceLinkTests/Requests/SDLRPCRequestNotificationSpec.m b/SmartDeviceLinkTests/Requests/SDLRPCRequestNotificationSpec.m new file mode 100644 index 000000000..4751c9361 --- /dev/null +++ b/SmartDeviceLinkTests/Requests/SDLRPCRequestNotificationSpec.m @@ -0,0 +1,41 @@ +// +// SDLRPCRequestNotificationSpec.m +// SmartDeviceLinkTests +// +// Created by Nicole on 2/14/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> + +#import "SDLNotificationConstants.h" +#import "SDLAddCommand.h" +#import "SDLRPCRequestNotification.h" + + +QuickSpecBegin(SDLRPCRequestNotificationSpec) + +describe(@"A request notification", ^{ + __block SDLRPCRequest *testRequest = nil; + __block NSString *testName = nil; + + beforeEach(^{ + testRequest = [[SDLAddCommand alloc] initWithName:@"testRequest"]; + testName = SDLDidReceiveAddCommandResponse; + }); + + it(@"Should initialize correctly with initWithName:object:rpcRequest:", ^{ + SDLRPCRequestNotification *testNotification = [[SDLRPCRequestNotification alloc] initWithName:testName object:nil rpcRequest:testRequest]; + + expect(testNotification.name).to(equal(testName)); + expect(testNotification.userInfo).to(equal(@{SDLNotificationUserInfoObject: testRequest})); + expect(testNotification.object).to(beNil()); + expect(testNotification.request).to(equal(testRequest)); + expect([testNotification isRequestKindOfClass:SDLRPCRequest.class]).to(beTrue()); + expect([testNotification isRequestMemberOfClass:SDLAddCommand.class]).to(beTrue()); + }); +}); + +QuickSpecEnd + diff --git a/SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m b/SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m new file mode 100644 index 000000000..4805eeba2 --- /dev/null +++ b/SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m @@ -0,0 +1,95 @@ +// +// SDLRPCResponseOperationSpec.m +// SmartDeviceLinkTests +// +// Created by Nicole on 2/20/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> + +#import "SDLGetAppServiceDataResponse.h" +#import "SDLOnAppServiceData.h" +#import "SDLRPCResponseOperation.h" +#import "TestConnectionManager.h" + +QuickSpecBegin(SDLRPCResponseOperationSpec) + +describe(@"sending responses and notifications", ^{ + __block TestConnectionManager *testConnectionManager = nil; + __block SDLRPCResponseOperation *testOperation = nil; + __block NSOperationQueue *testOperationQueue = nil; + + beforeEach(^{ + testOperation = nil; + testConnectionManager = [[TestConnectionManager alloc] init]; + + testOperationQueue = [[NSOperationQueue alloc] init]; + testOperationQueue.name = @"com.sdl.RPCResponse.testqueue"; + testOperationQueue.maxConcurrentOperationCount = 3; + }); + + context(@"when a single request succeeds", ^{ + __block __kindof SDLRPCMessage *sendRPC = nil; + + beforeEach(^{ + sendRPC = [[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:[[SDLAppServiceData alloc] init]]; + }); + + it(@"should correctly send the rpc", ^{ + testOperation = [[SDLRPCResponseOperation alloc] initWithConnectionManager:testConnectionManager rpc:sendRPC]; + + [testOperationQueue addOperation:testOperation]; + [NSThread sleepForTimeInterval:0.1]; + + expect(testConnectionManager.receivedRequests).toEventually(contain(sendRPC)); + }); + }); + + context(@"when multiple request succeed", ^{ + __block NSMutableArray< __kindof SDLRPCMessage *> *sendRPCs = nil; + __block int rpcCount = (int)testOperationQueue.maxConcurrentOperationCount + 3; + + beforeEach(^{ + sendRPCs = [NSMutableArray array]; + for (int i = 0; i < rpcCount; i += 1) { + [sendRPCs addObject:[[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:[[SDLAppServiceData alloc] init]]]; + } + }); + + it(@"should correctly send all of the rpcs", ^{ + for (int i = 0; i < rpcCount; i += 1) { + testOperation = [[SDLRPCResponseOperation alloc] initWithConnectionManager:testConnectionManager rpc:sendRPCs[i]]; + [testOperationQueue addOperation:testOperation]; + } + + [NSThread sleepForTimeInterval:0.1]; + + expect(testConnectionManager.receivedRequests.count).toEventually(equal(rpcCount)); + expect(testConnectionManager.receivedRequests).toEventually(equal(sendRPCs)); + }); + }); + + context(@"when a requst is cancelled", ^{ + __block __kindof SDLRPCMessage *sendRPC = nil; + + beforeEach(^{ + sendRPC = [[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:[[SDLAppServiceData alloc] init]]; + }); + + it(@"should not send the rpc", ^{ + testOperation = [[SDLRPCResponseOperation alloc] initWithConnectionManager:testConnectionManager rpc:sendRPC]; + + [testOperationQueue addOperation:testOperation]; + [testOperationQueue cancelAllOperations]; + + [NSThread sleepForTimeInterval:0.1]; + + expect(testConnectionManager.receivedRequests).toEventually(beEmpty()); + }); + }); +}); + +QuickSpecEnd + diff --git a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h index e1a24418b..b538249b0 100644 --- a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h +++ b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN /** * All received requests. Chronological order. The 0th element will be the first request received; the nth request will be the n+1th request received. */ -@property (copy, nonatomic, readonly) NSMutableArray<__kindof SDLRPCRequest *> *receivedRequests; +@property (copy, nonatomic, readonly) NSMutableArray<__kindof SDLRPCMessage *> *receivedRequests; /** * The block passed for the last request send with sendRequest:withCompletionHandler: diff --git a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m index 4c8ea3a50..e081b3ac5 100644 --- a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m +++ b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m @@ -21,15 +21,20 @@ NS_ASSUME_NONNULL_BEGIN return nil; } - _receivedRequests = [NSMutableArray<__kindof SDLRPCRequest *> array]; + _receivedRequests = [NSMutableArray<__kindof SDLRPCMessage *> array]; return self; } -- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { self.lastRequestBlock = handler; - request.correlationID = [self test_nextCorrelationID]; - [self.receivedRequests addObject:request]; + if ([request isKindOfClass:SDLRPCRequest.class]) { + SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; + requestRPC.correlationID = [self test_nextCorrelationID]; + [self.receivedRequests addObject:requestRPC]; + } else { + [self.receivedRequests addObject:request]; + } } - (void)sendConnectionManagerRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { @@ -98,7 +103,7 @@ NS_ASSUME_NONNULL_BEGIN } - (void)reset { - _receivedRequests = [NSMutableArray<__kindof SDLRPCRequest *> array]; + _receivedRequests = [NSMutableArray<__kindof SDLRPCMessage *> array]; _lastRequestBlock = nil; } |