diff --git a/.gitignore b/.gitignore index 052522f..dd74d9d 100644 --- a/.gitignore +++ b/.gitignore @@ -69,4 +69,4 @@ fastlane/screenshots fastlane/test_output fastlane/README.md -Tests/Credentials.swift \ No newline at end of file +Tests/Credentials.swift diff --git a/Source/Models/ChargeState.swift b/Source/Models/ChargeState.swift index 21674c2..e297c68 100644 --- a/Source/Models/ChargeState.swift +++ b/Source/Models/ChargeState.swift @@ -31,7 +31,7 @@ public class ChargeState { public let chargerVoltage: Int public let chargingState: ChargingState public let estBatteryRange: Double - public let euVehicle: Bool + public let euVehicle: Bool? public let fastChargerPresent: Bool public let fastChargerType: String? public let idealBatteryRange: Double @@ -39,7 +39,7 @@ public class ChargeState { public let managedChargingStartTime: Date? public let managedChargingUserCanceled: Bool public let maxRangeChargeCounter: Int - public let motorizedChargePort: Bool + public let motorizedChargePort: Bool? public let notEnoughPowerToHeat: Bool? public let scheduledChargingPending: Bool public let scheduledChargingStartTime: Date? @@ -74,7 +74,7 @@ public class ChargeState { chargerVoltage = dictionary["charger_voltage"] as! Int chargingState = ChargingState(rawValue: dictionary["charging_state"] as! String)! estBatteryRange = dictionary["est_battery_range"] as! Double - euVehicle = dictionary["eu_vehicle"] as! Bool + euVehicle = dictionary["eu_vehicle"] as? Bool fastChargerPresent = dictionary["fast_charger_present"] as! Bool fastChargerType = dictionary["fast_charger_type"] as? String idealBatteryRange = dictionary["ideal_battery_range"] as! Double @@ -86,7 +86,7 @@ public class ChargeState { } managedChargingUserCanceled = dictionary["managed_charging_user_canceled"] as! Bool maxRangeChargeCounter = dictionary["max_range_charge_counter"] as! Int - motorizedChargePort = dictionary["motorized_charge_port"] as! Bool + motorizedChargePort = dictionary["motorized_charge_port"] as? Bool notEnoughPowerToHeat = dictionary["not_enough_power_to_heat"] as? Bool scheduledChargingPending = dictionary["scheduled_charging_pending"] as! Bool if let timestamp = dictionary["scheduled_charging_start_time"] as? Double { diff --git a/Source/Models/ClimateState.swift b/Source/Models/ClimateState.swift new file mode 100644 index 0000000..5392057 --- /dev/null +++ b/Source/Models/ClimateState.swift @@ -0,0 +1,23 @@ +import Foundation + +public struct ClimateState { + let insideTemp: Double + let outsideTemp: Double + let driverTempSetting: Double + let passengerTempSetting: Double + let isAutoConditioningOn: Bool + let isFrontDefrosterOn: Bool + let isRearDefrosterOn: Bool + let fanStatus: Int? + + init(dict: [String: Any]) { + insideTemp = dict["inside_temp"] as! Double + outsideTemp = dict["outside_temp"] as! Double + driverTempSetting = dict["driver_temp_setting"] as! Double + passengerTempSetting = dict["passenger_temp_setting"] as! Double + isAutoConditioningOn = dict["is_auto_conditioning_on"] as! Bool + isFrontDefrosterOn = dict["is_front_defroster_on"] as! Bool + isRearDefrosterOn = dict["is_rear_defroster_on"] as! Bool + fanStatus = dict["fan_status"] as? Int + } +} diff --git a/Source/Requests/AuthenticateRequest.swift b/Source/Requests/AuthenticateRequest.swift index 3757d41..a7f8bc6 100644 --- a/Source/Requests/AuthenticateRequest.swift +++ b/Source/Requests/AuthenticateRequest.swift @@ -16,35 +16,29 @@ public struct AuthenticateRequest: RequestProtocol { } public func execute(completion: @escaping (Result) -> Void) { - let params: [String: AnyObject] = [ - "email": username as NSString, - "password": password as NSString, - "grant_type": grantType as NSString, - "client_id": clientIdentifier as NSString, - "client_secret": clientSecret as NSString - ] + let params = [ + "email": username, + "password": password, + "grant_type": grantType, + "client_id": clientIdentifier, + "client_secret": clientSecret + ] WebRequest.request( path: path, method: method, params: params) { response, error in - if let error = error { - DispatchQueue.main.async { + DispatchQueue.main.async { + if let error = error { completion(Result.failure(error)) - } - } else { - guard let responseDictionary = response as? [String: AnyObject] else { - DispatchQueue.main.async { + } else { + guard let responseDictionary = response as? [String: AnyObject] else { completion(Result.failure(APIError())) + return } - return - } - do { - let result = try Result.success(Token(dictionary: responseDictionary)) - DispatchQueue.main.async { + do { + let result = try Result.success(Token(dictionary: responseDictionary)) completion(result) - } - } catch let error { - DispatchQueue.main.async { + } catch { completion(Result.failure(error)) } } diff --git a/Source/Requests/ChargeStateRequest.swift b/Source/Requests/ChargeStateRequest.swift index e54d724..6f75979 100644 --- a/Source/Requests/ChargeStateRequest.swift +++ b/Source/Requests/ChargeStateRequest.swift @@ -19,17 +19,13 @@ public struct ChargeStateRequest: RequestProtocol { path: path, method: method, accessToken: accessToken) { response, error in - if let error = error { - DispatchQueue.main.async { + DispatchQueue.main.async { + if let error = error { completion(Result.failure(error)) - } - } else if let response = response as? [String: [String: Any]], - let dictionary = response["response"] { - DispatchQueue.main.async { + } else if let response = response as? [String: [String: Any]], + let dictionary = response["response"] { completion(Result.success(ChargeState(dictionary: dictionary))) - } - } else { - DispatchQueue.main.async { + } else { completion(Result.failure(APIError())) } } diff --git a/Source/Requests/ClimateStateRequest.swift b/Source/Requests/ClimateStateRequest.swift new file mode 100644 index 0000000..412a636 --- /dev/null +++ b/Source/Requests/ClimateStateRequest.swift @@ -0,0 +1,35 @@ +import Foundation + +public struct ClimateStateRequest: RequestProtocol { + typealias CompletionType = ClimateState + var path: String { + return "/api/1/vehicles/\(vehicleIdentifier)/data_request/climate_state" + } + let method = WebRequest.RequestMethod.get + let accessToken: String + let vehicleIdentifier: String + + public init(accessToken: String, vehicleIdentifier: String) { + self.accessToken = accessToken + self.vehicleIdentifier = vehicleIdentifier + } + + public func execute(completion: @escaping (Result) -> Void) { + WebRequest.request( + path: path, + method: method, + accessToken: accessToken) { response, error in + if let error = error { + DispatchQueue.main.async { + completion(Result.failure(error)) + } + return + } + let responseDict = response as! [String: [String: Any]] + let dataDict = responseDict["response"]! + DispatchQueue.main.async { + completion(Result.success(ClimateState(dict: dataDict))) + } + } + } +} diff --git a/Source/Requests/HVACRequests.swift b/Source/Requests/HVACRequests.swift new file mode 100644 index 0000000..c0bdc79 --- /dev/null +++ b/Source/Requests/HVACRequests.swift @@ -0,0 +1,49 @@ +import Foundation + +public struct HVACRequest: RequestProtocol { + public enum HVACState { + case on + case off + } + typealias CompletionType = Bool + var path: String { + switch state { + case .on: + return "/api/1/vehicles/\(vehicleIdentifier)/command/auto_conditioning_start" + case .off: + return "/api/1/vehicles/\(vehicleIdentifier)/command/auto_conditioning_stop" + } + } + let method = WebRequest.RequestMethod.post + let accessToken: String + let vehicleIdentifier: String + let state: HVACState + + public init(accessToken: String, vehicleIdentifier: String, state: HVACState) { + self.accessToken = accessToken + self.vehicleIdentifier = vehicleIdentifier + self.state = state + } + + public func execute(completion: @escaping (Result) -> Void) { + WebRequest.request( + path: path, + method: method, + accessToken: accessToken) { response, error in + if let error = error { + DispatchQueue.main.async { + completion(Result.failure(error)) + } + } else if let response = response as? [String: [String: Any]], + let resultBool = response["response"]?["result"] as? Bool { + DispatchQueue.main.async { + completion(Result.success(resultBool)) + } + } else { + DispatchQueue.main.async { + completion(Result.failure(APIError())) + } + } + } + } +} diff --git a/Source/Requests/ListVehiclesRequest.swift b/Source/Requests/ListVehiclesRequest.swift index 74cebe6..7ea5ea0 100644 --- a/Source/Requests/ListVehiclesRequest.swift +++ b/Source/Requests/ListVehiclesRequest.swift @@ -15,19 +15,15 @@ public struct ListVehiclesRequest: RequestProtocol { path: path, method: method, accessToken: accessToken) { response, error in - if let error = error { - DispatchQueue.main.async { + DispatchQueue.main.async { + if let error = error { completion(Result.failure(error)) - } - } else { - guard let responseArray = response?["response"] as? [[String: AnyObject]] else { - DispatchQueue.main.async { + } else { + guard let responseArray = response?["response"] as? [[String: AnyObject]] else { completion(Result.failure(APIError())) + return } - return - } - let vehicles = responseArray.flatMap { return Vehicle(dictionary: $0) } - DispatchQueue.main.async { + let vehicles = responseArray.flatMap { return Vehicle(dictionary: $0) } completion(Result.success(vehicles)) } } diff --git a/Source/Requests/LockRequest.swift b/Source/Requests/LockRequest.swift index 1c44f24..0d78541 100644 --- a/Source/Requests/LockRequest.swift +++ b/Source/Requests/LockRequest.swift @@ -30,17 +30,13 @@ public struct LockRequest: RequestProtocol { path: path, method: method, accessToken: accessToken) { response, error in - if let error = error { - DispatchQueue.main.async { + DispatchQueue.main.async { + if let error = error { completion(Result.failure(error)) - } - } else if let response = response as? [String: [String: Any]], - let resultBool = response["response"]?["result"] as? Bool { - DispatchQueue.main.async { + } else if let response = response as? [String: [String: Any]], + let resultBool = response["response"]?["result"] as? Bool { completion(Result.success(resultBool)) - } - } else { - DispatchQueue.main.async { + } else { completion(Result.failure(APIError())) } } diff --git a/Source/Requests/MobileEnabledForVehicleRequest.swift b/Source/Requests/MobileEnabledForVehicleRequest.swift index 9c986b0..142c43f 100644 --- a/Source/Requests/MobileEnabledForVehicleRequest.swift +++ b/Source/Requests/MobileEnabledForVehicleRequest.swift @@ -19,17 +19,13 @@ struct MobileEnabledForVehicleRequest: RequestProtocol { path: path, method: method, accessToken: accessToken) { response, error in - if let error = error { - DispatchQueue.main.async { + DispatchQueue.main.async { + if let error = error { completion(Result.failure(error)) - } - } else if let response = response as? [String: Bool], - let responseBool = response["response"] { - DispatchQueue.main.async { + } else if let response = response as? [String: Bool], + let responseBool = response["response"] { completion(Result.success(responseBool)) - } - } else { - DispatchQueue.main.async { + } else { completion(Result.failure(APIError())) } } diff --git a/Source/Requests/OpenChargePortRequest.swift b/Source/Requests/OpenChargePortRequest.swift index b2804d1..51c3a8a 100644 --- a/Source/Requests/OpenChargePortRequest.swift +++ b/Source/Requests/OpenChargePortRequest.swift @@ -19,17 +19,13 @@ public struct OpenChargePortRequest: RequestProtocol { path: path, method: method, accessToken: accessToken) { response, error in - if let error = error { - DispatchQueue.main.async { + DispatchQueue.main.async { + if let error = error { completion(Result.failure(error)) - } - } else if let response = response as? [String: [String: Any]], - let resultBool = response["response"]?["result"] as? Bool { - DispatchQueue.main.async { + } else if let response = response as? [String: [String: Any]], + let resultBool = response["response"]?["result"] as? Bool { completion(Result.success(resultBool)) - } - } else { - DispatchQueue.main.async { + } else { completion(Result.failure(APIError())) } } diff --git a/Source/Requests/SetTemperaturesRequest.swift b/Source/Requests/SetTemperaturesRequest.swift new file mode 100644 index 0000000..e1c78cb --- /dev/null +++ b/Source/Requests/SetTemperaturesRequest.swift @@ -0,0 +1,43 @@ +import Foundation + +public struct SetTemperaturesRequest: RequestProtocol { + typealias CompletionType = Bool + var path: String { + return "/api/1/vehicles/\(vehicleIdentifier)/command/set_temps" + } + let method = WebRequest.RequestMethod.post + let accessToken: String + let vehicleIdentifier: String + let driverTemp: Double + let passengerTemp: Double + + public init(accessToken: String, vehicleIdentifier: String, driverTemp: Double, passengerTemp: Double) { + self.accessToken = accessToken + self.vehicleIdentifier = vehicleIdentifier + self.driverTemp = driverTemp + self.passengerTemp = passengerTemp + } + + public func execute(completion: @escaping (Result) -> Void) { + WebRequest.request( + path: path, + method: method, + params: ["driver_temp": "\(driverTemp)", "passenger_temp": "\(passengerTemp)"], + accessToken: accessToken) { response, error in + if let error = error { + DispatchQueue.main.async { + completion(Result.failure(error)) + } + } else if let response = response as? [String: [String: Any]], + let resultBool = response["response"]?["result"] as? Bool { + DispatchQueue.main.async { + completion(Result.success(resultBool)) + } + } else { + DispatchQueue.main.async { + completion(Result.failure(APIError())) + } + } + } + } +} diff --git a/Source/WebRequest.swift b/Source/WebRequest.swift index 7d4e2e0..ee90a50 100644 --- a/Source/WebRequest.swift +++ b/Source/WebRequest.swift @@ -1,19 +1,15 @@ import Foundation -class WebRequest { +final class WebRequest { enum RequestMethod: String { case get = "GET" case post = "POST" case put = "PUT" } - private init() { - - } - static private func clientURLRequest( path: String, - params: [String: AnyObject]? = nil, + params: [String: String] = [:], accessToken: String? = nil) -> URLRequest { var components = URLComponents() @@ -22,17 +18,15 @@ class WebRequest { components.path = path var request = URLRequest(url: components.url!) - if let params = params { - var paramString = "" - for (key, value) in params { - let escapedKey = (key as NSString).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! - let escapedValue = (value as! NSString).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! - paramString += "\(escapedKey)=\(escapedValue)&" - } - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - request.httpBody = paramString.data(using: String.Encoding.utf8) - } + let bodyString = params.flatMap { args -> String? in + guard let escapedKey = args.key.percentageEncoded else { return nil } + guard let escapedValue = args.value.percentageEncoded else { return nil } + return escapedKey + "=" + escapedValue + }.joined(separator: "&") + + request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") + request.httpBody = bodyString.data(using: .utf8) if let accessToken = accessToken { request.addValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization") @@ -44,7 +38,8 @@ class WebRequest { static public func request( path: String, method: RequestMethod, - params: [String: AnyObject]? = nil, accessToken: String? = nil, + params: [String: String] = [:], + accessToken: String? = nil, completion: @escaping (_ response: AnyObject?, _ error: Error?) -> Void) { dataTask( request: clientURLRequest( @@ -61,9 +56,9 @@ class WebRequest { completion: @escaping (_ response: AnyObject?, _ error: Error?) -> Void) { var request = request request.httpMethod = method.rawValue - let session = URLSession(configuration: URLSessionConfiguration.default) + let session = URLSession(configuration: .default) - let task = session.dataTask(with: request as URLRequest) { data, response, error -> Void in + let task = session.dataTask(with: request) { data, _, error -> Void in if let error = error { completion(nil, error) return @@ -78,3 +73,9 @@ class WebRequest { task.resume() } } + +private extension String { + var percentageEncoded: String? { + return addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) + } +} diff --git a/Tesla-API.xcodeproj/project.pbxproj b/Tesla-API.xcodeproj/project.pbxproj index 5176192..f394ae6 100644 --- a/Tesla-API.xcodeproj/project.pbxproj +++ b/Tesla-API.xcodeproj/project.pbxproj @@ -73,7 +73,34 @@ FC99DFD91F1FBBE100013FE9 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC99DFD71F1FBBE100013FE9 /* Error.swift */; }; FC99DFDA1F1FBBE100013FE9 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC99DFD71F1FBBE100013FE9 /* Error.swift */; }; FC99DFDB1F1FBBE100013FE9 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC99DFD71F1FBBE100013FE9 /* Error.swift */; }; + FCB9328220FB913700D19874 /* ClimateStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328120FB913700D19874 /* ClimateStateRequest.swift */; }; + FCB9328320FB913700D19874 /* ClimateStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328120FB913700D19874 /* ClimateStateRequest.swift */; }; + FCB9328420FB913700D19874 /* ClimateStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328120FB913700D19874 /* ClimateStateRequest.swift */; }; + FCB9328520FB913700D19874 /* ClimateStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328120FB913700D19874 /* ClimateStateRequest.swift */; }; + FCB9328720FB917F00D19874 /* ClimateState.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328620FB917F00D19874 /* ClimateState.swift */; }; + FCB9328820FB917F00D19874 /* ClimateState.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328620FB917F00D19874 /* ClimateState.swift */; }; + FCB9328920FB917F00D19874 /* ClimateState.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328620FB917F00D19874 /* ClimateState.swift */; }; + FCB9328A20FB917F00D19874 /* ClimateState.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328620FB917F00D19874 /* ClimateState.swift */; }; + FCB9328C20FB9B3A00D19874 /* ClimateStateRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328B20FB9B3A00D19874 /* ClimateStateRequestTests.swift */; }; + FCB9328D20FB9B3A00D19874 /* ClimateStateRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328B20FB9B3A00D19874 /* ClimateStateRequestTests.swift */; }; + FCB9328E20FB9B3A00D19874 /* ClimateStateRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328B20FB9B3A00D19874 /* ClimateStateRequestTests.swift */; }; + FCB9329020FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328F20FBADE700D19874 /* SetTemperaturesRequest.swift */; }; + FCB9329120FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328F20FBADE700D19874 /* SetTemperaturesRequest.swift */; }; + FCB9329220FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328F20FBADE700D19874 /* SetTemperaturesRequest.swift */; }; + FCB9329320FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9328F20FBADE700D19874 /* SetTemperaturesRequest.swift */; }; + FCB9329520FBB50B00D19874 /* SetTemperaturesRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329420FBB50B00D19874 /* SetTemperaturesRequestTests.swift */; }; + FCB9329620FBB50B00D19874 /* SetTemperaturesRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329420FBB50B00D19874 /* SetTemperaturesRequestTests.swift */; }; + FCB9329720FBB50B00D19874 /* SetTemperaturesRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329420FBB50B00D19874 /* SetTemperaturesRequestTests.swift */; }; + FCB9329920FBB91100D19874 /* HVACRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329820FBB91100D19874 /* HVACRequests.swift */; }; + FCB9329A20FBB91100D19874 /* HVACRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329820FBB91100D19874 /* HVACRequests.swift */; }; + FCB9329B20FBB91100D19874 /* HVACRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329820FBB91100D19874 /* HVACRequests.swift */; }; + FCB9329C20FBB91100D19874 /* HVACRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329820FBB91100D19874 /* HVACRequests.swift */; }; + FCB9329E20FBB97500D19874 /* HVACRequestsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329D20FBB97500D19874 /* HVACRequestsTests.swift */; }; + FCB9329F20FBB97500D19874 /* HVACRequestsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329D20FBB97500D19874 /* HVACRequestsTests.swift */; }; + FCB932A020FBB97500D19874 /* HVACRequestsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB9329D20FBB97500D19874 /* HVACRequestsTests.swift */; }; FCD161971F1E79F0003FE381 /* Tesla-API.h in Headers */ = {isa = PBXBuildFile; fileRef = FCD161901F1E793F003FE381 /* Tesla-API.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FCE31678205E3284004EF4B0 /* TeslaAPITestsEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE31677205E3284004EF4B0 /* TeslaAPITestsEmpty.swift */; }; + FCE3167A205E3284004EF4B0 /* TeslaAPI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FCD1615D1F1E7844003FE381 /* TeslaAPI.framework */; }; FCE825FC1F8C068F00B72C08 /* ChargeStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE825FB1F8C068F00B72C08 /* ChargeStateRequest.swift */; }; FCE825FD1F8C068F00B72C08 /* ChargeStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE825FB1F8C068F00B72C08 /* ChargeStateRequest.swift */; }; FCE825FE1F8C068F00B72C08 /* ChargeStateRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE825FB1F8C068F00B72C08 /* ChargeStateRequest.swift */; }; @@ -114,6 +141,13 @@ remoteGlobalIDString = FC48F96B1F1E7E4800D2400B; remoteInfo = TeslaAPI_tvOS; }; + FCE3167B205E3284004EF4B0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FC6195CD1F1C074300144FD8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FCD1615C1F1E7844003FE381; + remoteInfo = TeslaAPI_iOS; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -135,6 +169,13 @@ FC80D5011F2CE6FD0013F6DF /* ListVehiclesRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListVehiclesRequest.swift; sourceTree = ""; }; FC99DFD21F1FB41400013FE9 /* Token.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Token.swift; sourceTree = ""; }; FC99DFD71F1FBBE100013FE9 /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = ""; }; + FCB9328120FB913700D19874 /* ClimateStateRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClimateStateRequest.swift; sourceTree = ""; }; + FCB9328620FB917F00D19874 /* ClimateState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClimateState.swift; sourceTree = ""; }; + FCB9328B20FB9B3A00D19874 /* ClimateStateRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClimateStateRequestTests.swift; sourceTree = ""; }; + FCB9328F20FBADE700D19874 /* SetTemperaturesRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetTemperaturesRequest.swift; sourceTree = ""; }; + FCB9329420FBB50B00D19874 /* SetTemperaturesRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetTemperaturesRequestTests.swift; sourceTree = ""; }; + FCB9329820FBB91100D19874 /* HVACRequests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HVACRequests.swift; sourceTree = ""; }; + FCB9329D20FBB97500D19874 /* HVACRequestsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HVACRequestsTests.swift; sourceTree = ""; }; FCD1615D1F1E7844003FE381 /* TeslaAPI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TeslaAPI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FCD1618D1F1E793F003FE381 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; FCD1618F1F1E793F003FE381 /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = ""; }; @@ -143,6 +184,9 @@ FCD161921F1E793F003FE381 /* WebRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRequest.swift; sourceTree = ""; }; FCD161941F1E79C3003FE381 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; FCD161951F1E79C3003FE381 /* TeslaAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeslaAPITests.swift; sourceTree = ""; }; + FCE31675205E3284004EF4B0 /* TeslaAPITestsEmpty.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TeslaAPITestsEmpty.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + FCE31677205E3284004EF4B0 /* TeslaAPITestsEmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeslaAPITestsEmpty.swift; sourceTree = ""; }; + FCE31679205E3284004EF4B0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; FCE825FB1F8C068F00B72C08 /* ChargeStateRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChargeStateRequest.swift; sourceTree = ""; }; FCE826001F8C075C00B72C08 /* ChargeState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChargeState.swift; sourceTree = ""; }; FCE826051F8C092C00B72C08 /* ChargeStateRequestTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChargeStateRequestTests.swift; sourceTree = ""; }; @@ -203,17 +247,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + FCE31672205E3284004EF4B0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FCE3167A205E3284004EF4B0 /* TeslaAPI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ FC27C97D1F4995070064E1AE /* Request Tests */ = { isa = PBXGroup; children = ( + FCE826051F8C092C00B72C08 /* ChargeStateRequestTests.swift */, + FCB9328B20FB9B3A00D19874 /* ClimateStateRequestTests.swift */, + FCB9329D20FBB97500D19874 /* HVACRequestsTests.swift */, FC27C97E1F4995240064E1AE /* ListVehiclesRequestTests.swift */, FC27C97F1F4995240064E1AE /* LockRequestTests.swift */, FC27C9801F4995240064E1AE /* MobileEnabledForRequestTests.swift */, FC27C9811F4995240064E1AE /* OpenChargePortRequestTests.swift */, - FCE826051F8C092C00B72C08 /* ChargeStateRequestTests.swift */, + FCB9329420FBB50B00D19874 /* SetTemperaturesRequestTests.swift */, ); path = "Request Tests"; sourceTree = ""; @@ -223,6 +278,7 @@ children = ( FCD1618C1F1E793F003FE381 /* Source */, FCD161931F1E79C3003FE381 /* Tests */, + FCE31676205E3284004EF4B0 /* TeslaAPITestsEmpty */, FC6195D71F1C074300144FD8 /* Products */, ); sourceTree = ""; @@ -237,6 +293,7 @@ FC48F9791F1E7E5800D2400B /* TeslaAPI.framework */, FC48F9881F1E7F1500D2400B /* TeslaAPI_macOS_Tests.xctest */, FC48F9971F1E7F2500D2400B /* TeslaAPI_tvOS_Tests.xctest */, + FCE31675205E3284004EF4B0 /* TeslaAPITestsEmpty.xctest */, ); name = Products; sourceTree = ""; @@ -253,11 +310,14 @@ isa = PBXGroup; children = ( FCE946461F2CF10E004913FC /* AuthenticateRequest.swift */, + FCE825FB1F8C068F00B72C08 /* ChargeStateRequest.swift */, + FCB9328120FB913700D19874 /* ClimateStateRequest.swift */, + FCB9329820FBB91100D19874 /* HVACRequests.swift */, FC80D5011F2CE6FD0013F6DF /* ListVehiclesRequest.swift */, FC75EC521F2E4AD7007ED697 /* LockRequest.swift */, FC1B80961F49883500D24310 /* MobileEnabledForVehicleRequest.swift */, FC75EC571F2E613A007ED697 /* OpenChargePortRequest.swift */, - FCE825FB1F8C068F00B72C08 /* ChargeStateRequest.swift */, + FCB9328F20FBADE700D19874 /* SetTemperaturesRequest.swift */, ); path = Requests; sourceTree = ""; @@ -280,6 +340,7 @@ isa = PBXGroup; children = ( FCE826001F8C075C00B72C08 /* ChargeState.swift */, + FCB9328620FB917F00D19874 /* ClimateState.swift */, FC99DFD71F1FBBE100013FE9 /* Error.swift */, FC99DFD21F1FB41400013FE9 /* Token.swift */, FCD1618F1F1E793F003FE381 /* Vehicle.swift */, @@ -299,6 +360,15 @@ path = Tests; sourceTree = ""; }; + FCE31676205E3284004EF4B0 /* TeslaAPITestsEmpty */ = { + isa = PBXGroup; + children = ( + FCE31677205E3284004EF4B0 /* TeslaAPITestsEmpty.swift */, + FCE31679205E3284004EF4B0 /* Info.plist */, + ); + path = TeslaAPITestsEmpty; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -463,13 +533,31 @@ productReference = FCD1615D1F1E7844003FE381 /* TeslaAPI.framework */; productType = "com.apple.product-type.framework"; }; + FCE31674205E3284004EF4B0 /* TeslaAPITestsEmpty */ = { + isa = PBXNativeTarget; + buildConfigurationList = FCE3167F205E3284004EF4B0 /* Build configuration list for PBXNativeTarget "TeslaAPITestsEmpty" */; + buildPhases = ( + FCE31671205E3284004EF4B0 /* Sources */, + FCE31672205E3284004EF4B0 /* Frameworks */, + FCE31673205E3284004EF4B0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + FCE3167C205E3284004EF4B0 /* PBXTargetDependency */, + ); + name = TeslaAPITestsEmpty; + productName = TeslaAPITestsEmpty; + productReference = FCE31675205E3284004EF4B0 /* TeslaAPITestsEmpty.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ FC6195CD1F1C074300144FD8 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0830; + LastSwiftUpdateCheck = 0920; LastUpgradeCheck = 0910; ORGANIZATIONNAME = JagCesar; TargetAttributes = { @@ -503,6 +591,10 @@ LastSwiftMigration = 0910; ProvisioningStyle = Manual; }; + FCE31674205E3284004EF4B0 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = FC6195D01F1C074300144FD8 /* Build configuration list for PBXProject "Tesla-API" */; @@ -524,6 +616,7 @@ FC48F9171F1E7B6200D2400B /* TeslaAPI_iOS_Tests */, FC48F9871F1E7F1500D2400B /* TeslaAPI_macOS_Tests */, FC48F9961F1E7F2500D2400B /* TeslaAPI_tvOS_Tests */, + FCE31674205E3284004EF4B0 /* TeslaAPITestsEmpty */, ); }; /* End PBXProject section */ @@ -578,6 +671,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + FCE31673205E3284004EF4B0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -585,10 +685,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FCB9329E20FBB97500D19874 /* HVACRequestsTests.swift in Sources */, FC27C98B1F4995240064E1AE /* OpenChargePortRequestTests.swift in Sources */, + FCB9328C20FB9B3A00D19874 /* ClimateStateRequestTests.swift in Sources */, FC27C9821F4995240064E1AE /* ListVehiclesRequestTests.swift in Sources */, FCF2A1291FA32CE900BA5C3F /* Credentials.swift in Sources */, FCE826061F8C092C00B72C08 /* ChargeStateRequestTests.swift in Sources */, + FCB9329520FBB50B00D19874 /* SetTemperaturesRequestTests.swift in Sources */, FC27C97A1F4993E10064E1AE /* ModelMocks.swift in Sources */, FC27C9851F4995240064E1AE /* LockRequestTests.swift in Sources */, FC27C9881F4995240064E1AE /* MobileEnabledForRequestTests.swift in Sources */, @@ -602,15 +705,19 @@ files = ( FC48F9AE1F1E7FCE00D2400B /* Vehicle.swift in Sources */, FC48F9AA1F1E7FBA00D2400B /* WebRequest.swift in Sources */, + FCB9329A20FBB91100D19874 /* HVACRequests.swift in Sources */, FC48F9A61F1E7FB600D2400B /* TeslaAPI.swift in Sources */, + FCB9328820FB917F00D19874 /* ClimateState.swift in Sources */, FCE825FD1F8C068F00B72C08 /* ChargeStateRequest.swift in Sources */, FC75EC4C1F2E068E007ED697 /* RequestProtocol.swift in Sources */, + FCB9328320FB913700D19874 /* ClimateStateRequest.swift in Sources */, FC75EC541F2E4F2F007ED697 /* LockRequest.swift in Sources */, FCE946481F2CF10E004913FC /* AuthenticateRequest.swift in Sources */, FC1B80981F498A2E00D24310 /* MobileEnabledForVehicleRequest.swift in Sources */, FCE826021F8C075C00B72C08 /* ChargeState.swift in Sources */, FC80D5031F2CE6FD0013F6DF /* ListVehiclesRequest.swift in Sources */, FC99DFD91F1FBBE100013FE9 /* Error.swift in Sources */, + FCB9329120FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */, FC75EC591F2E6219007ED697 /* OpenChargePortRequest.swift in Sources */, FC99DFD61F1FB65A00013FE9 /* Token.swift in Sources */, ); @@ -622,15 +729,19 @@ files = ( FC48F9AD1F1E7FCE00D2400B /* Vehicle.swift in Sources */, FC48F9A91F1E7FBA00D2400B /* WebRequest.swift in Sources */, + FCB9329B20FBB91100D19874 /* HVACRequests.swift in Sources */, FC48F9A51F1E7FB500D2400B /* TeslaAPI.swift in Sources */, + FCB9328920FB917F00D19874 /* ClimateState.swift in Sources */, FCE825FE1F8C068F00B72C08 /* ChargeStateRequest.swift in Sources */, FC75EC4A1F2E068C007ED697 /* RequestProtocol.swift in Sources */, + FCB9328420FB913700D19874 /* ClimateStateRequest.swift in Sources */, FC75EC551F2E4F30007ED697 /* LockRequest.swift in Sources */, FCE946491F2CF10E004913FC /* AuthenticateRequest.swift in Sources */, FC1B80991F498A2F00D24310 /* MobileEnabledForVehicleRequest.swift in Sources */, FCE826031F8C075C00B72C08 /* ChargeState.swift in Sources */, FC80D5041F2CE6FD0013F6DF /* ListVehiclesRequest.swift in Sources */, FC99DFDA1F1FBBE100013FE9 /* Error.swift in Sources */, + FCB9329220FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */, FC75EC5A1F2E621A007ED697 /* OpenChargePortRequest.swift in Sources */, FC99DFD51F1FB65A00013FE9 /* Token.swift in Sources */, ); @@ -642,15 +753,19 @@ files = ( FC48F9AC1F1E7FCD00D2400B /* Vehicle.swift in Sources */, FC48F9A81F1E7FBA00D2400B /* WebRequest.swift in Sources */, + FCB9329C20FBB91100D19874 /* HVACRequests.swift in Sources */, FC48F9A41F1E7FB400D2400B /* TeslaAPI.swift in Sources */, + FCB9328A20FB917F00D19874 /* ClimateState.swift in Sources */, FCE825FF1F8C068F00B72C08 /* ChargeStateRequest.swift in Sources */, FC75EC491F2E068C007ED697 /* RequestProtocol.swift in Sources */, + FCB9328520FB913700D19874 /* ClimateStateRequest.swift in Sources */, FC75EC561F2E4F30007ED697 /* LockRequest.swift in Sources */, FCE9464A1F2CF10E004913FC /* AuthenticateRequest.swift in Sources */, FC1B809A1F498A3000D24310 /* MobileEnabledForVehicleRequest.swift in Sources */, FCE826041F8C075C00B72C08 /* ChargeState.swift in Sources */, FC80D5051F2CE6FD0013F6DF /* ListVehiclesRequest.swift in Sources */, FC99DFDB1F1FBBE100013FE9 /* Error.swift in Sources */, + FCB9329320FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */, FC75EC5B1F2E621A007ED697 /* OpenChargePortRequest.swift in Sources */, FC99DFD41F1FB65A00013FE9 /* Token.swift in Sources */, ); @@ -660,10 +775,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FCB9329F20FBB97500D19874 /* HVACRequestsTests.swift in Sources */, FC27C98C1F4995240064E1AE /* OpenChargePortRequestTests.swift in Sources */, + FCB9328D20FB9B3A00D19874 /* ClimateStateRequestTests.swift in Sources */, FC27C9831F4995240064E1AE /* ListVehiclesRequestTests.swift in Sources */, FCF2A12A1FA32CE900BA5C3F /* Credentials.swift in Sources */, FC6F72E61FA12BB3009BF1C4 /* ChargeStateRequestTests.swift in Sources */, + FCB9329620FBB50B00D19874 /* SetTemperaturesRequestTests.swift in Sources */, FC27C97B1F4993E10064E1AE /* ModelMocks.swift in Sources */, FC27C9861F4995240064E1AE /* LockRequestTests.swift in Sources */, FC27C9891F4995240064E1AE /* MobileEnabledForRequestTests.swift in Sources */, @@ -675,10 +793,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FCB932A020FBB97500D19874 /* HVACRequestsTests.swift in Sources */, FC27C98D1F4995250064E1AE /* OpenChargePortRequestTests.swift in Sources */, + FCB9328E20FB9B3A00D19874 /* ClimateStateRequestTests.swift in Sources */, FC27C9841F4995240064E1AE /* ListVehiclesRequestTests.swift in Sources */, FCF2A12B1FA32CE900BA5C3F /* Credentials.swift in Sources */, FC6F72E71FA12BB4009BF1C4 /* ChargeStateRequestTests.swift in Sources */, + FCB9329720FBB50B00D19874 /* SetTemperaturesRequestTests.swift in Sources */, FC27C97C1F4993E10064E1AE /* ModelMocks.swift in Sources */, FC27C9871F4995240064E1AE /* LockRequestTests.swift in Sources */, FC27C98A1F4995240064E1AE /* MobileEnabledForRequestTests.swift in Sources */, @@ -692,20 +813,32 @@ files = ( FC48F9AF1F1E7FCE00D2400B /* Vehicle.swift in Sources */, FC99DFD31F1FB41400013FE9 /* Token.swift in Sources */, + FCB9329920FBB91100D19874 /* HVACRequests.swift in Sources */, FC48F9AB1F1E7FBB00D2400B /* WebRequest.swift in Sources */, + FCB9328720FB917F00D19874 /* ClimateState.swift in Sources */, FCE825FC1F8C068F00B72C08 /* ChargeStateRequest.swift in Sources */, FC75EC4B1F2E068D007ED697 /* RequestProtocol.swift in Sources */, + FCB9328220FB913700D19874 /* ClimateStateRequest.swift in Sources */, FCE946471F2CF10E004913FC /* AuthenticateRequest.swift in Sources */, FC75EC531F2E4AD7007ED697 /* LockRequest.swift in Sources */, FC1B80971F49883500D24310 /* MobileEnabledForVehicleRequest.swift in Sources */, FCE826011F8C075C00B72C08 /* ChargeState.swift in Sources */, FC80D5021F2CE6FD0013F6DF /* ListVehiclesRequest.swift in Sources */, FC99DFD81F1FBBE100013FE9 /* Error.swift in Sources */, + FCB9329020FBADE700D19874 /* SetTemperaturesRequest.swift in Sources */, FC75EC581F2E613A007ED697 /* OpenChargePortRequest.swift in Sources */, FC48F9A71F1E7FB600D2400B /* TeslaAPI.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + FCE31671205E3284004EF4B0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FCE31678205E3284004EF4B0 /* TeslaAPITestsEmpty.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -724,6 +857,11 @@ target = FC48F96B1F1E7E4800D2400B /* TeslaAPI_tvOS */; targetProxy = FC48F99D1F1E7F2500D2400B /* PBXContainerItemProxy */; }; + FCE3167C205E3284004EF4B0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = FCD1615C1F1E7844003FE381 /* TeslaAPI_iOS */; + targetProxy = FCE3167B205E3284004EF4B0 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -1098,6 +1236,42 @@ }; name = Release; }; + FCE3167D205E3284004EF4B0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = TeslaAPITestsEmpty/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = se.jagcesar.TeslaAPITestsEmpty; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + FCE3167E205E3284004EF4B0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = TeslaAPITestsEmpty/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = se.jagcesar.TeslaAPITestsEmpty; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1173,6 +1347,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + FCE3167F205E3284004EF4B0 /* Build configuration list for PBXNativeTarget "TeslaAPITestsEmpty" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FCE3167D205E3284004EF4B0 /* Debug */, + FCE3167E205E3284004EF4B0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = FC6195CD1F1C074300144FD8 /* Project object */; diff --git a/Tesla-API.xcodeproj/xcshareddata/xcschemes/TeslaAPI_iOS.xcscheme b/Tesla-API.xcodeproj/xcshareddata/xcschemes/TeslaAPI_iOS.xcscheme index 1b31b68..d97b4f0 100644 --- a/Tesla-API.xcodeproj/xcshareddata/xcschemes/TeslaAPI_iOS.xcscheme +++ b/Tesla-API.xcodeproj/xcshareddata/xcschemes/TeslaAPI_iOS.xcscheme @@ -30,7 +30,7 @@ shouldUseLaunchSchemeArgsEnv = "YES"> + skipped = "YES"> + + + + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/TeslaAPITestsEmpty/TeslaAPITestsEmpty.swift b/TeslaAPITestsEmpty/TeslaAPITestsEmpty.swift new file mode 100644 index 0000000..bf81469 --- /dev/null +++ b/TeslaAPITestsEmpty/TeslaAPITestsEmpty.swift @@ -0,0 +1,27 @@ +// +// TeslaAPITestsEmpty.swift +// TeslaAPITestsEmpty +// +// Created by JagCesar on 2018-03-17. +// Copyright © 2018 JagCesar. All rights reserved. +// + +import XCTest + +class TeslaAPITestsEmpty: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } +} diff --git a/Tests/Credentials.swift b/Tests/Credentials.swift new file mode 100644 index 0000000..11005e4 --- /dev/null +++ b/Tests/Credentials.swift @@ -0,0 +1,17 @@ +import XCTest +@testable import TeslaAPI + +extension TeslaAPITests { + func username() -> String { + return "" + } + func password() -> String { + return "" + } + func accessToken() -> String { + return "" + } + func vehicleIdentifier() -> String { + return "" + } +} diff --git a/Tests/Request Tests/ClimateStateRequestTests.swift b/Tests/Request Tests/ClimateStateRequestTests.swift new file mode 100644 index 0000000..838e0aa --- /dev/null +++ b/Tests/Request Tests/ClimateStateRequestTests.swift @@ -0,0 +1,19 @@ +import XCTest +@testable import TeslaAPI + +extension TeslaAPITests { + func testClimateState() { + let waitExpectation = expectation(description: "Climate state") + ClimateStateRequest( + accessToken: accessToken(), + vehicleIdentifier: vehicleIdentifier()).execute { result in + switch result { + case .success(_): + waitExpectation.fulfill() + case .failure(_): + XCTFail() + } + } + waitForExpectations(timeout: 30, handler: nil) + } +} diff --git a/Tests/Request Tests/HVACRequestsTests.swift b/Tests/Request Tests/HVACRequestsTests.swift new file mode 100644 index 0000000..bce2f5f --- /dev/null +++ b/Tests/Request Tests/HVACRequestsTests.swift @@ -0,0 +1,48 @@ +import XCTest +@testable import TeslaAPI + +extension TeslaAPITests { + func testEnableHvac() { + let waitExpectation = expectation(description: "Enable HVAC") + + HVACRequest( + accessToken: accessToken(), + vehicleIdentifier: vehicleIdentifier(), + state: .on).execute { result in + XCTAssert(Thread.isMainThread) + switch result { + case .success(let result): + if result { + waitExpectation.fulfill() + } else { + XCTFail() + } + case .failure(_): + XCTFail() + } + } + waitForExpectations(timeout: 30, handler: nil) + } + + func testDisableHvac() { + let waitExpectation = expectation(description: "Disable HVAC") + + HVACRequest( + accessToken: accessToken(), + vehicleIdentifier: vehicleIdentifier(), + state: .off).execute { result in + XCTAssert(Thread.isMainThread) + switch result { + case .success(let result): + if result { + waitExpectation.fulfill() + } else { + XCTFail() + } + case .failure(_): + XCTFail() + } + } + waitForExpectations(timeout: 30, handler: nil) + } +} diff --git a/Tests/Request Tests/SetTemperaturesRequestTests.swift b/Tests/Request Tests/SetTemperaturesRequestTests.swift new file mode 100644 index 0000000..0013067 --- /dev/null +++ b/Tests/Request Tests/SetTemperaturesRequestTests.swift @@ -0,0 +1,27 @@ +import XCTest +@testable import TeslaAPI + +extension TeslaAPITests { + func testSetTemperatures() { + let waitExpectation = expectation(description: "Set temperatures") + + SetTemperaturesRequest( + accessToken: accessToken(), + vehicleIdentifier: vehicleIdentifier(), + driverTemp: 21, + passengerTemp: 21).execute { result in + XCTAssert(Thread.isMainThread) + switch result { + case .success(let result): + if result == true { + waitExpectation.fulfill() + } else { + XCTFail() + } + case .failure(_): + XCTFail() + } + } + waitForExpectations(timeout: 30, handler: nil) + } +}