The persistent connection channel software development kit (SDK) encapsulates Internet of Things (IoT) protocols to deliver downstream data from the cloud. It allows apps to subscribe to and publish messages, and supports a request-response model.
| Dependent SDKs | Overview |
| Log | A basic dependent SDK that provides unified client logging, log level control, and log fencing by module. |
| API channel | Provides API channel capabilities and basic environment configuration. |
Initialization
To initialize the SDK, see SDK Initialization.
Usage notes
The SDK encapsulates interfaces for upstream Remote Procedure Call (RPC) requests, subscriptions, and unsubscriptions. For more information about the interfaces, see Persistent Connection Service.
The SDK uses shortened topic paths. For example, the full topic for an upstream request is /sys/{productKey}/{deviceName}/app/up/test/publish.
For upstream requests, the SDK automatically adds the /sys/{productKey}/{deviceName}/app/up/ prefix. When you call the SDK, you only need to enter /test/publish as the input parameter.
For a corresponding downstream topic, such as the full topic for a device status change /sys/{productKey}/{deviceName}/app/down/things/status, the SDK callback only exposes /things/status. The SDK automatically truncates the /sys/{productKey}/{deviceName}/app/down prefix.
Business request-response model
This interface encapsulates an RPC process. The following example shows the internal logic for attaching an account to a channel. The topic for this operation is /sys/{productKey}/{deviceName}/app/up/account/bind.
Before you publish data to this topic, you must subscribe to the corresponding reply topic: /sys/{productKey}/{deviceName}/app/down/account/bind_reply. After the subscription is successful, you can publish the data. When the IoT User Center receives the data published to the /sys/{productKey}/{deviceName}/app/up/account/bind topic, it completes the account attachment logic. Then, it publishes a response to the /sys/{productKey}/{deviceName}/app/down/account/bind_reply topic. When the SDK receives data from this reply topic, it sends the response to the application through the `respHandler` callback. This completes the entire process.
#import <AlinkAppExpress/LKAppExpress.h>
// The persistent connection channel SDK automatically adds the '/sys/{productKey}/{deviceName}/app/up' part.
// When you use this API, simply pass the latter part of the topic, which is '/account/bind'.
[[LKAppExpress sharedInstance] invokeWithTopic : @"/account/bind" opts:nil params:@{@"iotToken":iotToken}
respHandler:^(LKAppExpResponse * _Nonnull response) {
LKAELogDebug(@"bindAccount result : %@", response);
}];Subscribe to a topic
The persistent connection channel SDK uses the Message Queuing Telemetry Transport (MQTT) protocol and is based on a publish/subscribe model. After you subscribe to a topic, you receive messages when other services or devices publish to it. The following example shows how to subscribe to a topic that reports property changes for a user's attached devices.
The full topic path is /sys/{productKey}/{deviceName}/app/down/thing/properties. The persistent connection channel SDK automatically adds the /sys/{productKey}/{deviceName}/app/down prefix. When you call the API to subscribe to a topic, you only need to provide the topic suffix, which is /thing/properties. This rule applies to other topics as well.
#import <AlinkAppExpress/LKAppExpress.h>
// This example shows how to subscribe to property change events for a user's attached devices. For more information, see the API reference.
[[LKAppExpress sharedInstance]subscribe:@"/thing/properties" complete:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil) {
[_tipsLabel setText:@"Subscription successful"];
} else {
[_tipsLabel setText:@"Subscription failed"];
}
});
}];Unsubscribe from a topic
Unsubscribing is the reverse of subscribing. Both operations follow the same topic rules. The following example shows how to unsubscribe from the topic that reports property changes for a user's attached devices.
#import <AlinkAppExpress/LKAppExpress.h>
// For more information, see the API reference.
[[LKAppExpress sharedInstance]unsubscribe:@"/thing/properties" complete:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil) {
[_tipsLabel setText:@"Unsubscription successful"];
} else {
[_tipsLabel setText:@"Unsubscription failed"];
}
});
}];Publish data
The persistent connection channel SDK is based on a publish/subscribe model. It lets you subscribe to topics and publish data to them. The following example shows how to publish data to the topic /sys/{productKey}/{deviceName}/app/up/test/publish.
The persistent connection channel SDK automatically adds the /sys/{productKey}/{deviceName}/app/up prefix. When you call the API to publish data, you only need to provide the topic suffix, which is /test/publish.
#import <AlinkAppExpress/LKAppExpress.h>
NSString * text = @"{\"input\":\"Hello World\"}";
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
if (data == nil) {
return;
}
NSError *error;
NSDictionary *params = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (error) {
return;
}
[[LKAppExpress sharedInstance]publish:@"/test/publish" params:params
complete:^(NSError * _Nonnull error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil) {
[_tipsLabel setText:@"Publish successful"];
} else {
[_tipsLabel setText:@"Publish failed"];
}
});
}];Register a downstream listener
You can register a downstream listener to receive data from subscribed topics. For more information, see Persistent Connection Service Downstream Message API.
#import <AlinkAppExpress/LKAppExpress.h>
@interface TestDownstreamListener : NSObject <LKAppExpDownListener>
@end
@implementation TestDownstreamListener
- (void)onDownstream:(NSString * _Nonnull)topic data:(id _Nullable)data {
NSLog(@"onDownstream topic : %@", topic);
NSLog(@"onDownstream data : %@", data);
NSDictionary * replyDict = nil;
if ([data isKindOfClass:[NSString class]]) {
NSData * replyData = [data dataUsingEncoding:NSUTF8StringEncoding];
replyDict = [NSJSONSerialization JSONObjectWithData:replyData options:NSJSONReadingMutableLeaves error:nil];
} else if ([data isKindOfClass:[NSDictionary class]]) {
replyDict = data;
}
if (replyDict == nil) {
return;
}
}
- (BOOL)shouldHandle:(NSString * _Nonnull)topic {
if ([topic isEqualToString:@"/thing/properties"]) {
return YES;// Return YES to indicate interest in this topic. The SDK will then call [listener onDownstream:data:].
}
return NO;
}
@end
self.testListner = [TestDownstreamListener new];// The SDK does not hold a strong reference to this listener. The developer must ensure the listener is not released.
[[LKAppExpress sharedInstance]addDownStreamListener:YES listener:self.testListner]
Detach the persistent connection channel from an account
During initialization, the persistent connection channel is attached to an account. To detach the channel from the account, you can run the following code.
You must detach the persistent connection channel from the user account before you log out. Otherwise, the detachment operation will fail.
#import <AlinkAppExpress/LKAppExpress.h>
#import <IMSAuthentication/IMSCredentialManager.h>
#pragma mark - Detach the persistent connection channel
NSString *topic = @"/account/unbind";
[[LKAppExpress sharedInstance] invokeWithTopic:topic opts:nil params:@{} respHandler:^(LKAppExpResponse * _Nonnull response) {
if (![response successed]) {
IMSLifeLogVerbose(@"Failed to detach the persistent connection push");
}
}];