NOTICE - This software does not rely on any third party apis outside of Particle.io and Apple.inc. Anyone may request a Pull request, however no merges will be allowed add any other third party dependencies.
NOTE This software is to be considered untested at this point. Though some functionality seems to be working well it is an extensive framework and as such has not been thoroughly tested. Please submit requests for improvements or make a pull request to help chase down issues.
- The event subscriptions can only be done through deprecated APIs and a buggy stream subscription. A bug report has been submitted to address the issue.
- The OTP is not implemented for use with two factor authentication.
- Device claiming and wifi setup is not yet implemented.
- The example app is not very well thoughtout it is just a quick example of what the sdk can do and how it works.
Available on platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v8), .macCatalyst(.v15), .tvOS(.v15), .visionOS(.v1)]
How to login to the Particleio sdk. There are two ways to login to the cloud.
- Login with a token. If you already have a token provided perhaps through a login server or webhook, you can simply create a PCAccessToken and pass it to the PCAuthenticationManager or the PCContainer.
- Example:
import SwiftUI
import ParticleIoSDK
class SomeViewModel: ObservableObject {
@ObservedObject var container = PCContainer.shared
@ObservedObject var authMan = PCAuthenticationManager.shared
var name = ""
var password = ""
}
struct DocumentationView: View {
@ObservedObject private var model = SomeViewModel()
var body: some View {
if model.container.authenticationManager.isLoading {
ProgressView(value: model.container.authenticationManager.loadingProgress.fractionCompleted)
// or ProgressView(value: model.authMan.loadingProgress.fractionCompleted)
} else if model.container.userIsAuthenticated { // or model.authMan.userIsAuthenticated
Text("Logged In")
//get a device or something..
Button {
model.container.logout() { result in // or model.authMan.logout()
switch result {
case .success(let bool):
//bool should be true from server if no error exists
break
case .failure(let error):
//handle error
break
}
}
} label: {
Text("Log Out")
}
} else {
TextField("Username", text: $model.name)
TextField("Password", text: $model.password)
Button {
model.container.login(token: PCAccessToken(accessToken: "your_token") { result in
//or model.authMan.login...
switch result {
case .success(let bool):
//bool should be true from server if no error exists
break
case .failure(let error):
//handle error
break
}
}
} label: {
Text("Login")
}
}
}
}
#Preview {
DocumentationView()
}
- Get a login with your credentials.
Button {
model.container.login(credentials: PCCredentials(username: model.name, password: model.password)) { result in
//or model.authMan.login...
switch result {
case .success(let bool):
//bool should be true from server if no error exists
break
case .failure(let error):
//handle error
break
}
}
} label: {
Text("Login")
}
See docs for more info: PCContainer PCDevice
How to get a device.
The easiest way to get a device after logging in is to call on the container to get one.
You can also call a static func on PCDevice such as getDevice or getProductDevice.
static public func getProductDevice(deviceID: DeviceID?, productIdOrSlug: ProductID, token: PCAccessToken) async throws -> PCDevice
or list devices from PCContainer or PCDevice.
after you have a device you can manipulate it by using instance function calls
- Example:
//prefered use
//somewhere in the model
extension DeviceID {
static let myDevice = DeviceID("your_device_id")
}
Task {
let device = try await model.container.getDevice(deviceID: DeviceID.myDevice)
}
//alternative use
Task {
let device = try await model.container.getDevice(deviceID: DeviceID("Your_DeviceID"))
}
device.callFunction...
device.getVariable...
device.ping...
device.signal...
device.subscribe....
etc.
//These stub outs maybe helpful
//These are optional to open easier and less error prone functionality.
//Although these can all be initialized directly, it is more useful to make static instances in order to keep loose string constants out of your app.
extension OrganizationName {
public static let <#sandbox#> = OrganizationName("<#Sandbox#>")
}
extension ProductID {
public static let <#name#> = ProductID("<#your_product_id_or_slug#>")
}
extension DeviceID {
public static let <#name#> = DeviceID("<#your_device_id#>")
}
extension VariableName {
public static let <#name#> = VariableName("<#your_particle_program_defined_variable_name#>")
}
extension DeviceName {
public static let <#name#> = DeviceName("<#your_device_name#>")
}
extension EventName {
public static let <#name#> = EventName("<#your_particle_program_defined_event_name#>")
}
extension FunctionName {
public static let <#name#> = FunctionName("<#your_particle_program_defined_function_name#>")
}
extension FunctionArgument {
public static let <#name#> = FunctionArgument("<#your_particle_program_defined_argument#>")
}
extension ICCIDNumber {
static public let <#name#> = ICCIDNumber("<#your_iccic_number#>")
}
extension SerialNumber {
public static let <#name#> = SerialNumber("<#your_serial_number#>")
}
*/
#You can also interact with the following:
This type allows
This type allows
- Get User (Returning the representation of the currently authenticated user.)
- Update user
- Delete user
- Or Making a forgot password call.
When creating an API User or an User you can limit the scope of the user by assigning UserScopes. For a complete listing of available scope see the documentation of UserScopes
This type is used for interacting with sims