The Xcode workspace Example/MemfaultCloud.xcworkspace
contains a DemoApp
target. This is a very basic iOS app that demonstrates the functionality of this
library.
Before building the app, make sure to update the Project Key in
AppDelegate.swift
. To find your Project Key, log in to
https://app.memfault.com/ and navigate to Settings.
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Enable debug logs:
gMFLTLogLevel = .debug
MemfaultApi.configureSharedApi([
kMFLTProjectKey: "<YOUR_PROJECT_KEY_HERE>",
])
return true
}
}
Add this line to your dependencies list in your Package.swift:
.package(name: "MemfaultCloud", url: "https://github.com/memfault/memfault-ios-cloud.git", from: "2.2.1"),
In case you are using CocoaPods, you can add MemfaultCloud
as a dependency to
your Podfile
:
target 'MyApp' do
pod 'MemfaultCloud'
end
It's probably a good idea to specify the version to use. See the Podfile documentation for more information.
After adding the new dependency, run pod install
inside your terminal, or from
CocoaPods.app.
To use MemfaultCloud
without using a dependency manager such as CocoaPods,
just clone this repo and add the .h
and .m
files inside MemfaultCloud
folder to your project.
The MemfaultApi
class is the main class of the MemfaultCloud library. It is
recommended to use the MemfaultApi.sharedApi
property that returns the
singleton instance, instead of "manually" creating an instance. Using the
singleton ensures that requests to our servers are made sequentially, when
required.
Before using MemfaultApi.sharedApi
, you will need to configure it once and
only once by passing a configuration dictionary to
MemfaultApi.configureSharedApi([...])
The Project Key is the only mandatory piece of configuration. To find your Project Key, log in to https://app.memfault.com/ and navigate to Settings.
MemfaultApi.configureSharedApi([
kMFLTProjectKey: "<YOUR_PROJECT_KEY_HERE>",
])
The api.getLatestRelease
can be used to see if a device is up-to-date or
whether there is a new OTA update payload available for it.
The app is expected to be able to communicate with the device and fetch its
serial number, hardware version, current software version and type. Create a
MemfaultDeviceInfo
object from that information and pass it to
api.getLatestRelease
:
let deviceInfo = MemfaultDeviceInfo(
deviceSerial: "DEMO_SERIAL",
hardwareVersion: "proto",
softwareVersion: "1.0.0",
softwareType: "main")
MemfaultApi.sharedApi.getLatestRelease(for: deviceInfo) { (package, isUpToDate, error) in
if error != nil {
print("There was an error, handle it here.")
return
}
if package == nil {
print("Device is already up to date!")
return
}
print("Update available: \(package!.description)")
}
The MemfaultOtaPackage package
object has a location
property, which
contains the URL to the OTA payload.
The Memfault Firmware SDK packetizes data that needs to be sent back to Memfault's cloud into "chunks". See this tutorial for more information on the device/firmware details.
This iOS library contains a high-level API to submit the chunks to Memfault.
Getting the chunks out of the device and into the iOS app is part of the integration work. The assumption is that you already have a communication mechanism between the device and iOS app that can be leveraged.
// Array with Data objects, each with chunk bytes
// (produced by the Memfault Firmware SDK packetizer and sent
// to the iOS app to be posted to the cloud):
let chunks = [...]
MemfaultApi.shared.chunkSender(withDeviceSerial: "DEMO_SERIAL").postChunks(chunks)
The default queue implementation is RAM backed. Therefore, if the host app is killed or the iOS device is shutdown or rebooted, the contents of the queue are lost. This can be a reason to override the default queue implementation.
The library provides a "hook" to override the default queue implementation, by
setting the kMFLTChunkQueueProvider
configuration option to an object that
conforms to MemfaultChunkQueueProvider
:
class MyQueueProvider: MemfaultChunkQueueProvider {
func queue(withDeviceSerial deviceSerial: String) -> MemfaultChunkQueue {
// Get or create a queue for the given deviceSerial.
// The queue object needs to implement
// the MemfaultChunkQueue protocol.
let queue = ...
return queue
}
}
func bootMemfault() {
let queueProvider = MyQueueProvider()
MemfaultApi.configureSharedApi([
kMFLTProjectKey: "<YOUR_PROJECT_KEY_HERE>",
// Pass the custom queue provider in the configuration:
kMFLTChunkQueueProvider: queueProvider,
])
// If your queue implementation persists the contents of the
// queues between app restarts, you will need to call postChunks()
// after restarting the app. This re-registers the queues that were loaded
// from persistent storage and resumes the upload process again:
let deviceSerialsToResume = [ ... ]
for sn in deviceSerialsToResume {
MemfaultApi.shared.chunkSender(withDeviceSerial: sn).postChunks()
}
}
MemfaultCloud.h
contains detailed documentation for each API.
The Xcode workspace Example/MemfaultCloud.xcworkspace
also contains a
MemfaultCloud_Tests
scheme. To run the tests, select this scheme, then select
Product > Test (cmd + U).
See CHANGELOG.md file.