summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Beharry <justin.beharry@livio.io>2022-07-28 16:50:06 -0400
committerJustin Beharry <justin.beharry@livio.io>2022-07-28 16:50:06 -0400
commit6da2aae218f6d5798f8c908086ad2f888063b2a9 (patch)
tree3f89ccb3893358270ad4b343cd47b4f495837c13
parent7324ff60ac0e7174c9a372e12804d6c9072b7bc9 (diff)
downloadsdl_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.swift39
-rw-r--r--Example Apps/Example Swift/ProxyManager.swift1
-rw-r--r--RemoteControlManager.swift133
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj4
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 */,