TeslaSwift

Swift 库,用于访问 Tesla API,基于 Tesla JSON API (非官方)Tesla Fleet API

Swift Build Status

安装

Swift Package Manager

您可以使用 Swift Package Manager,并在 Package.swift 中指定依赖项,或者将依赖项添加到 Xcode

.Package(url: "https://github.com/jonasman/TeslaSwift.git", majorVersion: 10)

还有用于 Combine 的扩展 TeslaSwiftCombine

流式传输扩展为:TeslaSwiftStreaming,Combine TeslaSwiftStreamingCombine

Tesla API

目前有两个 Tesla API 可用

  1. 旧版 owner API
  2. 新的 Fleet API

您可以选择其中任何一个。如果要使用 FleetAPI,请使用 regionclientIdclientSecretredirectURI 初始化库

Fleet API 的应用程序注册

要使用新的 Fleet API,您需要注册您的应用程序。

按照 官方文档 中的步骤操作

  1. 创建私钥/公钥,并将公钥上传到网站
  2. Tesla Developer 创建一个新应用程序
  3. 获取合作伙伴令牌(使用此库)
  4. 注册您的应用程序(使用此库)

该库可以帮助您通过 2 个 API 获取合作伙伴令牌并注册您的应用程序

getPartnerToken()
registerApp(domain: String)

用法

Tesla 的服务器与 ATS 不兼容,因此您需要将以下内容添加到您的应用程序 Info.plist 中

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

导入模块

import TeslaSwift

如果需要,添加扩展模块(使用上一行代码)

import TeslaSwiftCombine

使用浏览器,使用您的 MyTesla 凭据执行身份验证

如果您使用 deeplinks,请将您的回调 URI 方案作为 URL Scheme 添加到您的应用程序中,位置在 info -> URL Types 下

 if let url = api.authenticateWebNativeURL() {
    UIApplication.shared.open(url)
}
...

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    Task { @MainActor in
        do {
            _ = try await api.authenticateWebNative(url: url)
            // Notify your code the auth is done
        } catch {
            print("Error")
        }
    }        
    return true
}

使用 webview 的替代方法(此方法没有电子邮件和 MFA 代码的自动填充)使用支持 MFA 的 web oAuth2 流程,使用您的 MyTesla 凭据执行身份验证

let teslaAPI = ...
let api = TeslaSwift(teslaAPI: teslaAPI)
let (webloginViewController, result) = api.authenticateWeb()
guard let webloginViewController else { return }
present(webloginViewController, animated: true, completion: nil)
Task { @MainActor in
        do {
             _ = try await result()
             self.messageLabel.text = "Authentication success"
        } catch let error {
            // error
       }
}

要在 SwiftUI 中执行身份验证,请创建一个 UIViewControllerRepresentable 以将 UIViewController 注入到 SwiftUI 视图中

import TeslaSwift
import SwiftUI

struct TeslaWebLogin: UIViewControllerRepresentable {
    let teslaAPI = ...
    let api = TeslaSwift(teslaAPI: teslaAPI)    
    
    func makeUIViewController(context: Context) -> TeslaWebLoginViewController {
        let (webloginViewController, result) = api.authenticateWeb()        
        Task { @MainActor in
                do {
                     _ = try await result()
                    print("Authentication success")                    
                    guard api.isAuthenticated else { return }
                    Task { @MainActor in
                        do {
                            let vehicles = try await api.getVehicles()

                            // post process your vehicles here

                        } catch {
                            print("Error",error)
                        }
                    }                    
                } catch let error {
                    print("Error", error)
               }
        }        
        return webloginViewController!
    }
    
    func updateUIViewController(_ uiViewController: TeslaWebLoginViewController, context: Context) {
    }
    
}
import SwiftUI
struct TeslaLogin: View {
    var body: some View {
        VStack {
            TeslaWebLogin()
        }
    }
}

将公钥上传到车辆

身份验证后,某些车辆可能需要接收您的公钥。

if let url = api.urlToSendPublicKeyToVehicle(domain: yourDomain) {
    UIApplication.shared.open(url)
}

这将打开 Tesla 应用程序,并将公钥发送到应用程序中选定的车辆。

令牌重用

身份验证后,将 AuthToken 存储在一个安全的地方。下次应用程序启动时,您可以重用该令牌

let teslaAPI = ...
let api = TeslaSwift(teslaAPI: teslaAPI)
api.reuse(token: previousToken)

车辆数据

获取车辆列表的示例

class CarsViewController: ViewController {
    func showCars() {
      do {
        let response = try await api.getVehicles()
        self.data = response
        self.tableView.reloadData()
      } catch let error {
        //Process error
     }
}

流式传输

导入模块

import TeslaSwiftStreaming

如果需要,添加扩展模块(使用上一行代码)

import TeslaSwiftStreamingCombine
class CarsViewController: ViewController {

  func showStream() {
    stream = TeslaStreaming(teslaSwift: api)
    do {
        for try await event in try await stream.openStream(vehicle: myVehicle) {
            switch event {
                case .open:
                    // Open
                case .event(let streamEvent):
                    self.data.append(streamEvent)
                    self.tableView.reloadData()
                case .error(let error):                    
                    // Process error
                case .disconnet:
                    break
            }
        }
    } catch let error {
    // error
    }

    // After some events...
    stream.closeStream()
   }
}

编码器和解码器

如果您需要 JSON 编码器和解码器,该库提供了预先配置好的,可用于 Tesla 的 JSON 格式

public let teslaJSONEncoder: JSONEncoder
public let teslaJSONDecoder: JSONDecoder

选项

您可以通过设置以下内容来启用调试:api.debuggingEnabled = true。调试日志使用 Unified Logging,可以通过过滤 subsystem: Tesla Swift 找到

其他功能

身份验证完成后,该库将管理访问令牌。当令牌过期时,该库将使用刷新令牌请求新令牌。

推荐

如果您想购买 Tesla 或注册邮件列表,并使用我的推荐作为对此库的“感谢”,请访问:http://ts.la/joao290

使用此库的应用程序

缺少您的应用程序?请打开 PR 或 issue

许可证

MIT 许可证 (MIT)

版权所有 (c) 2016 João Nunes

特此授予任何人免费获得本软件和相关文档文件(“软件”)的副本的权利,以处理本软件,不受限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售本软件的副本的权利,并允许向其提供本软件的人员这样做,但须符合以下条件:

上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。

本软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于适销性、特定用途的适用性和非侵权性的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同、侵权或其他行为中,由本软件或本软件的使用或其他处理引起的,与之相关或与之相关。