diff options
author | Justin Beharry <justin.beharry@livio.io> | 2022-07-28 16:50:06 -0400 |
---|---|---|
committer | Justin Beharry <justin.beharry@livio.io> | 2022-07-28 16:50:06 -0400 |
commit | 6da2aae218f6d5798f8c908086ad2f888063b2a9 (patch) | |
tree | 3f89ccb3893358270ad4b343cd47b4f495837c13 | |
parent | 7324ff60ac0e7174c9a372e12804d6c9072b7bc9 (diff) | |
download | sdl_ios-6da2aae218f6d5798f8c908086ad2f888063b2a9.tar.gz |
Create remote control climate example
Add new menu item and toggle AC on or off
-rw-r--r-- | Example Apps/Example Swift/MenuManager.swift | 39 | ||||
-rw-r--r-- | Example Apps/Example Swift/ProxyManager.swift | 1 | ||||
-rw-r--r-- | RemoteControlManager.swift | 133 | ||||
-rw-r--r-- | SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 4 |
4 files changed, 176 insertions, 1 deletions
diff --git a/Example Apps/Example Swift/MenuManager.swift b/Example Apps/Example Swift/MenuManager.swift index 092670559..607ae8f21 100644 --- a/Example Apps/Example Swift/MenuManager.swift +++ b/Example Apps/Example Swift/MenuManager.swift @@ -24,7 +24,8 @@ class MenuManager: NSObject { menuCellRecordInCarMicrophoneAudio(with: manager), menuCellDialNumber(with: manager), menuCellChangeTemplate(with: manager), - menuCellWithSubmenu(with: manager)] + menuCellWithSubmenu(with: manager), + menuCellRemoteControl(with: manager)] } /// Creates and returns the voice commands. The voice commands are menu items that are selected using the voice recognition system. @@ -206,6 +207,42 @@ private extension MenuManager { }) }) } + + /// Menu item that shows remote control example + /// + /// - Parameter manager: The SDL Manager + /// - Returns: A SDLMenuCell object + class func menuCellRemoteControl(with manager: SDLManager) -> SDLMenuCell { + + /// Lets give an example of 2 templates + var submenuItems = [SDLMenuCell]() + let errorMessage = "Changing the template failed" + + /// Non-Media + let submenuTitleNonMedia = "Climate Control" + submenuItems.append(SDLMenuCell(title: submenuTitleNonMedia, secondaryText: nil, tertiaryText: nil, icon: nil, secondaryArtwork: nil, voiceCommands: nil, handler: { (triggerSource) in + manager.screenManager.changeLayout(SDLTemplateConfiguration(predefinedLayout: .nonMedia)) { err in + if err != nil { + AlertManager.sendAlert(textField1: errorMessage, sdlManager: manager) + return + } + let remoteControlManager = RemoteControlManager(sdlManager: manager) + } + })) + + /// Graphic with Text + let submenuTitleGraphicText = "Radio Control" + submenuItems.append(SDLMenuCell(title: submenuTitleGraphicText, secondaryText: nil, tertiaryText: nil, icon: nil, secondaryArtwork: nil, voiceCommands: nil, handler: { (triggerSource) in + manager.screenManager.changeLayout(SDLTemplateConfiguration(predefinedLayout: .graphicWithText)) { err in + if err != nil { + AlertManager.sendAlert(textField1: errorMessage, sdlManager: manager) + return + } + } + })) + + return SDLMenuCell(title: "Remote Control", secondaryText: nil, tertiaryText: nil, icon: nil, secondaryArtwork: nil, submenuLayout: .list, subCells: submenuItems) + } } // MARK: - Menu Voice Commands diff --git a/Example Apps/Example Swift/ProxyManager.swift b/Example Apps/Example Swift/ProxyManager.swift index efd364784..e28b4dabc 100644 --- a/Example Apps/Example Swift/ProxyManager.swift +++ b/Example Apps/Example Swift/ProxyManager.swift @@ -94,6 +94,7 @@ private extension ProxyManager { let appIcon = UIImage(named: ExampleAppLogoName)?.withRenderingMode(.alwaysOriginal) lifecycleConfiguration.appIcon = appIcon != nil ? SDLArtwork(image: appIcon!, persistent: true, as: .PNG) : nil lifecycleConfiguration.appType = .default + lifecycleConfiguration.additionalAppTypes = [.remoteControl] lifecycleConfiguration.language = .enUs lifecycleConfiguration.languagesSupported = [.enUs, .esMx, .frCa] lifecycleConfiguration.ttsName = [SDLTTSChunk(text: "S D L", type: .text)] diff --git a/RemoteControlManager.swift b/RemoteControlManager.swift new file mode 100644 index 000000000..5b6418a9b --- /dev/null +++ b/RemoteControlManager.swift @@ -0,0 +1,133 @@ +// +// RemoteControlManager.swift +// SmartDeviceLink-Example-Swift +// +// Created by Beharry, Justin (J.S.) on 7/28/22. +// Copyright © 2022 smartdevicelink. All rights reserved. +// + +import Foundation +import SmartDeviceLink + +class RemoteControlManager { + private var sdlManager: SDLManager! + private var remoteControlCapabilities: SDLRemoteControlCapabilities! + private var climateModuleId: String! + private var consent: [Bool]! + + + init(sdlManager: SDLManager) { + self.sdlManager = sdlManager + /// Retrieve remote control information and store module ids + self.sdlManager.systemCapabilityManager.subscribe(capabilityType: .remoteControl) { (capability, subscribed, error) in + guard capability?.remoteControlCapability != nil else { return } + self.remoteControlCapabilities = capability?.remoteControlCapability + + + let firstClimateModule = self.remoteControlCapabilities.climateControlCapabilities?.first + let moduleId = firstClimateModule?.moduleInfo?.moduleId + + self.climateModuleId = moduleId + print("Climate Control Module Id ------------------------------------------------------------------------- \(self.climateModuleId ?? "Missing")") + + /// Get Consent to control module + let getInteriorVehicleDataConsent = SDLGetInteriorVehicleDataConsent(moduleType: .climate, moduleIds: [self.climateModuleId]) + self.sdlManager.send(request: getInteriorVehicleDataConsent, responseHandler: { (request, response, error) in + guard let res = response as? SDLGetInteriorVehicleDataConsentResponse else { return } + guard let allowed = res.allowed else { return } + let boolAllowed = allowed.map({ (bool) -> Bool in + return bool.boolValue + }) + + self.consent = boolAllowed + + self.showClimateControl() + }) + } + } + + private func subscribeVehicleData() { + sdlManager.subscribe(to: .SDLDidReceiveInteriorVehicleData) { (message) in + guard let onInteriorVehicleData = message as? SDLOnInteriorVehicleData else { return } + + print("Climate Data Changing") + print(onInteriorVehicleData.moduleData.climateControlData as Any) + } + } + + private func subscribeClimateData() { + let getInteriorVehicleData = SDLGetInteriorVehicleData(andSubscribeToModuleType: .climate, moduleId: climateModuleId) + self.sdlManager.send(request: getInteriorVehicleData) { (req, res, err) in + guard let response = res as? SDLGetInteriorVehicleDataResponse else { return } + + print(response) + } + } + + func turnOnAC() { + let climateDictionary: [String: Any] = [ + "acEnable": true as NSNumber & SDLBool + ] + + let climateControlData = SDLClimateControlData(dictionary: climateDictionary) + let moduleData = SDLModuleData(climateControlData: climateControlData) + let setInteriorVehicleData = SDLSetInteriorVehicleData(moduleData: moduleData) + + self.sdlManager.send(request: setInteriorVehicleData) { (request, response, error) in + guard response?.success.boolValue == true else { return } + } + } + + func turnOffAC() { + let climateDictionary: [String: Any] = [ + "acEnable": false as NSNumber & SDLBool + ] + + let climateControlData = SDLClimateControlData(dictionary: climateDictionary) + let moduleData = SDLModuleData(climateControlData: climateControlData) + let setInteriorVehicleData = SDLSetInteriorVehicleData(moduleData: moduleData) + + self.sdlManager.send(request: setInteriorVehicleData) { (request, response, error) in + guard response?.success.boolValue == true else { return } + } + } + + func showClimateControl() { + let screenManager = self.sdlManager.screenManager + screenManager.beginUpdates() + + screenManager.textField1 = "Climate Control Data" + screenManager.textField2 = "Press Buttons" + screenManager.textField3 = "Remote Control" + + self.subscribeVehicleData() + self.subscribeClimateData() + + + screenManager.changeLayout(SDLTemplateConfiguration(predefinedLayout: .nonMedia)) { err in + // This listener will be ignored, and will use the handler set in the endUpdates call. + } + + let acOnButton = SDLSoftButtonObject(name: "AC On", text: "AC On", artwork: nil) { (buttonPress, buttonEvent) in + guard buttonPress != nil else { return } + + self.turnOnAC() + } + + let acOffButton = SDLSoftButtonObject(name: "AC Off", text: "AC Off", artwork: nil) { (buttonPress, buttonEvent) in + guard buttonPress != nil else { return } + + self.turnOffAC() + } + + screenManager.softButtonObjects = [acOnButton, acOffButton] + + screenManager.endUpdates { error in + if error != nil { + // Print out the error if there is one and return early + print("Issue updating UI") + return + } + } + } +} diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 4476e9e0c..112dd2555 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -234,6 +234,7 @@ 1680B11C1A9CD7AD00DBD79E /* SDLProtocolMessageAssemblerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1680B1101A9CD7AD00DBD79E /* SDLProtocolMessageAssemblerSpec.m */; }; 1680B11D1A9CD7AD00DBD79E /* SDLProtocolMessageDisassemblerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1680B1111A9CD7AD00DBD79E /* SDLProtocolMessageDisassemblerSpec.m */; }; 1680B11E1A9CD7AD00DBD79E /* SDLProtocolReceivedMessageRouterSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1680B1121A9CD7AD00DBD79E /* SDLProtocolReceivedMessageRouterSpec.m */; }; + 1CFDAAA72893181200332B84 /* RemoteControlManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CFDAAA62893181200332B84 /* RemoteControlManager.swift */; }; 1E89B0DE2031636000A47992 /* SDLSeatControlDataSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E89B0DD2031636000A47992 /* SDLSeatControlDataSpec.m */; }; 1E89B0E2203196B800A47992 /* SDLSeatControlCapabilitiesSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E89B0E1203196B800A47992 /* SDLSeatControlCapabilitiesSpec.m */; }; 1EAA470E2032BF1D000FE74B /* SDLOnRCStatusSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EAA470D2032BF1D000FE74B /* SDLOnRCStatusSpec.m */; }; @@ -2100,6 +2101,7 @@ 1680B1101A9CD7AD00DBD79E /* SDLProtocolMessageAssemblerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLProtocolMessageAssemblerSpec.m; sourceTree = "<group>"; }; 1680B1111A9CD7AD00DBD79E /* SDLProtocolMessageDisassemblerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLProtocolMessageDisassemblerSpec.m; sourceTree = "<group>"; }; 1680B1121A9CD7AD00DBD79E /* SDLProtocolReceivedMessageRouterSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLProtocolReceivedMessageRouterSpec.m; sourceTree = "<group>"; }; + 1CFDAAA62893181200332B84 /* RemoteControlManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteControlManager.swift; sourceTree = SOURCE_ROOT; }; 1E89B0DD2031636000A47992 /* SDLSeatControlDataSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLSeatControlDataSpec.m; sourceTree = "<group>"; }; 1E89B0E1203196B800A47992 /* SDLSeatControlCapabilitiesSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLSeatControlCapabilitiesSpec.m; sourceTree = "<group>"; }; 1EAA470D2032BF1D000FE74B /* SDLOnRCStatusSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLOnRCStatusSpec.m; sourceTree = "<group>"; }; @@ -6866,6 +6868,7 @@ 5D1FF2D521304746000EB9B4 /* RPCPermissionsManager.swift */, 4A402558250026430080E159 /* SubscribeButtonManager.swift */, 5D1FF2D921304746000EB9B4 /* VehicleDataManager.swift */, + 1CFDAAA62893181200332B84 /* RemoteControlManager.swift */, ); name = SDL; sourceTree = "<group>"; @@ -9249,6 +9252,7 @@ 5D1FF2DF21304746000EB9B4 /* PerformInteractionManager.swift in Sources */, 5D1FF2ED2130479C000EB9B4 /* ConnectionIAPTableViewController.swift in Sources */, 5D1FF2DD21304746000EB9B4 /* RPCPermissionsManager.swift in Sources */, + 1CFDAAA72893181200332B84 /* RemoteControlManager.swift in Sources */, 5D1FF2E721304761000EB9B4 /* TextValidator.swift in Sources */, 4A402559250026430080E159 /* SubscribeButtonManager.swift in Sources */, 5D1FF2F8213047C1000EB9B4 /* AppDelegate.swift in Sources */, |