测试测试过 | ✗ |
Lang语言 | Obj-CObjective C |
许可证 | MIT |
发布最后发布 | 2016年3月 |
依赖 | |
AFNetworking | ~> 2.6.3 |
GBDeviceInfo | ~> 3.5.1 |
QSwizzle | ~> 0.2.0 |
BlocksKit | >= 0 |
Qwasi的ios-library
提供了一种方便的方法来访问Qwasi JSON-RPC API。
要运行示例项目,克隆仓库,并首先从Example目录运行pod install
。
Qwasi可在CocoaPods中获得。要安装它,只需将以下行添加到Podfile中:
pod 'Qwasi', '~>2.1.20'
Qwasi遵照MIT许可证。查看LICENSE文件以获取更多信息。
'AFJSONRPCClient'
'GBDeviceInfo', '~> 3.1.0'
'Emitter'
'QSwizzle', '~> 0.2.0'
Qwasi
有一个默认的单例Qwasi对象,最适合大多数用例。
Objective-C
Qwasi* qwasi = [Qwasi shared];
swift
let qwasi:Qwasi = Qwasi.shared()
通常不需要创建自己的Qwasi
对象,但如果有需要,这是简单的。
Objective-C
Qwasi* qwasi = [[Qwasi alloc] init];
swift
var qwasi:Qwasi = Qwasi()
QwasiConfig
默认情况下,任何Qwasi
实例都将尝试使用以下描述的默认配置。您可以通过设置配置对象显式设置或更改配置。每次更改配置时,您都需要重新注册设备。
Objective-C
qwasi.config = [QwasiConfig default];
swift
qwasi.config = QwasiConfig()
默认配置文件是Qwasi.plist
。您可以在Xcode项目中创建属性列表并将其添加到您的包中。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>apiUrl</key>
<string>https://sandbox.qwasi.com/v1</string>
<key>apiKey</key>
<string>Your Key</string>
<key>appId</key>
<string>Your id</string>
</dict>
</plist>
您可以使用以下方法从一个属性列表加载配置:
+ (instancetype)configWithFile:(NSString*)path
示例
Objective-C
QwasiConfig* config = [QwasiConfig configWithFile: @"myconfig"];
qwasi.config = config;
swift
var config:QwasiConfig? = QwasiConfig( file: "filename" )
注意:您不应在路径中包含.plist
扩展名
您可以使用以下方法动态创建运行时配置对象:
+ (instancetype)configWithURL:(NSURL*)url withApplication:(NSString*)app withKey:(NSString*)key;
示例
Objective-C
NSURL* url = [NSURL urlWithString: @"https://sandbox.qwasi.com/v1"];
QwasiConfig* config = [QwasiConfig configWithURL: url withApplication: @"Your app" withKey: @"Your key"];
qwasi.config = config;
swift
var url:NSURL = NSURL( string: "https://sandbox.qwasi.com/v1" )!
var config:QwasiConfig? = QwasiConfig( URL: url, withApplication: "Your app", withKey: "Your key")
qwasi.config = config
Qwasi 库使用类似于 nodejs 的发射器来发射事件。您可以通过使用注册方法之一注册监听器来监听这些事件。
- (void)on:(id)event listener:(id)listener;
- (void)once:(id)event listener:(id)listener;
- (void)on:(id)event selector:(SEL)selector target:(__weak id)target;
- (void)once:(id)event selector:(SEL)selector target:(__weak id)target;
早期注册
在设备注册之前注册事件处理程序非常重要。否则可能会出现竞争条件(即事件在处理程序创建之前发射)。
多次注册
多次调用具有相同代码段的注册方法会导致多个注册。例如,在如 viewDidLoad
这样的方法中注册将会导致同一块重复收到事件,可能会使您的代码处理消息两次。这是故意设计的,因为您可能希望在多个代码路径中处理消息。但这可能会导致意想不到的副作用。
Objective-C
- (void) viewDidLoad {
// This will cause this block to be registered EVERY time viewDidLoad is called
[qwasi on: @"message" listener: ^(QwasiMessage* message) {
// This will get called once for everytime viewDidLoad is called, per message
}];
}
swift
override func viewDidLoad() {
super.viewDidLoad()
// This will cause this block to be registered EVERY time viewDidLoad is called
qwasi.on( "message" selector: Selector( "messageHandler:") target: self)
}
移除监听器
您可以通过声明您的块并在稍后移除它来处理这个问题。
Objective-C
// Some where else in code
void (^myOnMessage)(QwasiMessage* message) = ^(QwasiMessage* message) {
// handle the message
};
- (void) viewDidLoad {
// Remove any existing blocks
[qwasi removeListener: @"message" listener: myOnMessage];
[qwasi on: @"message" listener: myOnMessage];
}
swift
//somewhere else
func messageHandler( message: QwasiMessage ){
// do what you will with the message
}
override func viewDidLoad() {
super.viewDidLoad()
// remove any existing selectors
qwasi.removeListener("message", selector: Selector("messageHandler:"), target: self)
qwasi.on( "message" selector: Selector( "messageHandler:") target: self)
}
您可以通过qwasi实例的message
事件接收消息。
示例
Objective-C
[qwasi on: @"message" listener: ^(QwasiMessage* message) {
// Do as you will with the message
}];
swift
//declared handler
qwasi.on( "message" selector: Selector( "onMessage:qwasi:") target: self)
func onMessage(message: QwasiMessage, qwasi: Qwasi) {
//handle the message how you will
}
QwasiErrorMessageFetchFailed
QwasiError
某些方法将具有一个失败回调参数,但所有方法将通过Qwasi
实例发射错误。您可以在实例上注册一个默认的错误处理程序并按需处理错误。
示例
Objective-C
[qwasi on: @"error" listener: ^(NSError* error) {
// Handle Errors here (see QwasiError.h)
if (error.domain == kQwasiErrorDomain) {
switch (error.code) {
default:
break;
}
}
DDLogError(@"%@", error);
}];
swift
//setup handler
qwasi.on("error", selector: Selector( "errorHandler:"), target: self)
//selector elsewhere
func errorHandler( error: NSError){
//Handle Error Here (QwasiError.h for more info)
if ( error.domain == kQwasiErrorDomain){
switch( error.code){
//do further handling here
default:
break
}
}
DDLogError(error.description)
}
与Qwasi互动的每个设备都需要一个唯一的设备令牌。此令牌在调用设备注册时返回。它应被存储以供未来的设备注册调用使用,以确保您可以正确跟踪该设备的活动。registerDevice只需要在每个应用程序启动时调用一次,除非您更改配置。
在Qwasi.h
中定义了许多registerDevice
重载,其中最简单和最有用的是
- (void)registerDevice:(NSString*)deviceToken withUserToken:(NSString*)userToken success:(void(^)(NSString* deviceToken))success;
示例
Objective-C
// Get our device token from the defaults
NSString* deviceToken = [[NSUserDefaults standardUserDefaults] valueForKey: DEVICE_TOKEN_KEY];
[qwasi registerDevice: deviceToken withUserToken: USER_TOKEN success: ^(NSString *deviceToken) {
// We need to store this for later as this is our unique device identifier
[[NSUserDefaults standardUserDefaults] setValue: deviceToken forKey: DEVICE_TOKEN_KEY];
}];
swift
//Get our device token from the defaults
let deviceToken: String? = defaults.stringForKey("deviceToken")
qwasi.registerDevice( deviceToken , withUserToken: "userToken", success: {
( deviceToken: String! ) -> Void in
// We need to store this for later as this is our Unique Device Identifier
NSUserDefaults.standardUserDefaults().setObject( deviceToken, forKey: "deviceToken")
NSUserDefaults.standardUserDefaults().syncronize()
//do other registration-sensitive activities
})
QwasiErrorDeviceRegistrationFailed
device.register
用户令牌基本上是您的设备标识符。一些开发者使用他们的客户ID或忠诚度ID号,这允许您使用此令牌从平台上对设备进行操作。这些不必是唯一的,可以用来使用单个用户令牌对设备进行分组。默认为""。
您可以通过deviceRegister
调用设置用户令牌,或者稍后通过qwasi对象进行设置。
示例
Objective-C
qwasi.userToken = @"My User Token";
swift
qwasi.userToken = "My User Token"
如果设备尚未注册,当调用注册时,用户令牌将被更新,否则将简单地使用 device.set_user_token
API 调用。
QwasiErrorSetUserTokenFailed
device.set_user_token
注销设备将从 Qwasi 数据库中完全删除记录。这适用于满足应用程序对隐私合规性的需求等情况。除非在这些情况下,否则应注销设备。
如果需要,可以使用以下方法注销设备:
- (void)unregisterDevice:(NSString*)deviceToke success:(void(^)())success failure:(void(^)(NSError* err))failure;
QwasiErrorDeviceUnregisterFailed
device.unregister
Qwasi 支持推送通知的简化注册。设备注册后,您可以在实例上设置 pushEnabled
或调用方法
- (void)registerForNotifications:(void(^)())success failure:(void(^)(NSError* err))failure;
示例
Objective-C
qwasi.pushEnabled = YES;
// if you want notification for when the push registration completed
// this event can occur more than once in an app life-cycle
[qwasi once: @"pushRegistered" listener: ^(NSString* pushToken) {
// do with the token as you will...
}];
// if you just want notification and the pushToken for youself
// this even will only occur once per app life-cycle
[qwasi once: @"pushToken" listener: ^(NSString* pushToken) {
// do with the token as you will...
}];
swift
qwasi.pushEnabled = true
// If you want notification for when the push registration has completed
// this event will happen once per app life-cycle
qwasi.once("pushRegistered", selector: Selector( "pushRegSelector:"), target: self)
// OR if you would like just notification and the pushToken
// this will happen once per app life-cycle
qwasi.once("pushToken", selector: Selector( "pushRegSelector:"), target: self)
// elsewhere in code...
func pushRegSelector( pushToken: String! ){
//do with the push token as you will...
}
注意: pushEnabled
标志是异步设置的,因此如果您需要使用该值,您必须在与示例中的完成事件之一接收到之后进行,因为实际上设置的内部操作存在竞争条件。
QwasiErrorPushRegistrationFailed
device.set_push_token
开发(调试)构建的应用程序将获取仅在 Apple 的沙盒推送网关上使用的 aps 沙盒推送令牌。同样,生产(发布)构建将默认获取一个生产推送令牌。行为可以通过应用程序配置文件进行覆盖,配置文件中有类似以下内容:
<key>aps-environment</key>
<string>development</string>
不支持编辑此配置文件,且不属于本文件的范畴。
Qwasi 通知管理器将尝试根据 DEBUG 预处理器头检测操作模式。要覆盖此模式,您需要在使用 Qwasi 平台的服务器强制传送通知之前手动设置此标志。
Objective-C
[QwasiNotificationManager shared].sandbox = YES; // or NO to force production
swift
QwasiNotificationManager.shared().sandbox = true // or false to force production
如果用户不允许推送通知或设备没有网络访问,某些通知可能会错过。如果您的应用有后台获取权限,即使在推送已禁用的情况下,您也将定期收到通知。库会通过抓取未读消息并创建 UILocalNotification 来模拟推送。
如果您的应用程序不支持后台获取,您可以定期调用
- (void)tryFetchUnreadMessages
将此方法放在您的UIApplicationDelegate中是一个好地方。
示例
Objective-C
- (void)applicationDidBecomeActive:(UIApplication *)application {
...
[qwasi tryFetchUnreadMessages];
}
swift
func applicationDidBecomeActive(application: UIApplication) {
...
qwasi.tryFetchUnreadMessages()
}
此方法不会生成通知。
QwasiErrorMessageFetchFailed
message.poll
qwasi
实例将为包含在消息中的标签发出特殊事件,可用于根据特殊标签过滤回调。
示例
Objective-C
// call this so messages with this tag won't get emitter to the default message
// hander as well
[qwasi filterTag: @"myCustomTag"];
[qwasi on: @"tag#myCustomTag listener: ^(QwasiMessage* message) {
// handle the message with the tag
}];
swift
// call this so messages with this tag won't get emitter to the default message
// hander as well
qwasi.filterTag( "myCustomTag")
qwasi.on("tag#myCustomTag", selector: "selectorName:", target: self)
Qwasi
AIM 通过频道支持任意消息组。API 简单。
- (void)subscribeToChannel:(NSString*)channel;
示例
Objective-C
[qwasi subscribeToChannel:@"baseball"];
swift
qwasi.subscribeToChannel( "baseball")
QwasiErrorChannelSubscribeFailed
channel.subscribe
- (void)unsubscribeFromChannel:(NSString*)channel;
示例
Objective-C
[qwasi unsubscribeFromChannel:@"baseball"];
swift
qwasi.unsubscribeFromChannel("baseball")
QwasiErrorChannelUnsubscribeFailed
channel.unsubscribe
Qwasi
平台支持在应用程序事件上触发,但必须提供事件。默认情况下,库将发送应用程序状态事件(打开、前台、后台)。您可以发送自定义事件并配置您的 AIM 如您所愿对其作出响应
- (void)postEvent:(NSString*)event withData:(id)data;
示例: Objective-C:
[qwasi postEvent: @"login" withData: @{ @"username": "bobvila" }];
swift
qwasi.postEvent( "login", withData: [ "username" : "bobvila"] )
Qwasi
SDK 可以提供设备位置并跟踪地理围栏和 iBeacon 事件。地理围栏和 iBeacon 必须通过 AIM 或 API 接口事先配置。
位置通过qwasi实例启用或禁用,一旦设备注册成功。
Objective-C
qwasi.locationEnabled = YES;
swift
qwasi.locationEnabled = true
只能有一个活动的 QwasiLocationManager
,您必须在启用位置之前设置此属性,默认为 foregroundManager。
Objective-C
// Default foreground manager
qwasi.locationManager = [QwasiLocationManager foreground];
// Or the background manager
qwasi.locationManager = [QwasiLocationManager background];
swift
qwasi.locationManager = QwasiLocationManager.foregroundManager()
qwasi.locationManager = QwasiLocationManager.backgroundManager()
注意:一旦在应用的第一次运行中设置了一个位置管理器,您可以更改它,但用户需要访问应用设置页面。您可以从后台(许可型)切换到前台(限制型)而无需更改设置。*
QwasiErrorLocationSyncFailed
location.fetch
类似于消息,位置事件也是通过实例上的发射器进行传递的。
示例
Objective-C
[qwasi on: @"location" listener: ^(QwasiLocation* location, QwasiLocationState state) {
switch (location.type) {
case QwasiLocationTypeCoordinate:
// This is a normal GPS update
break;
case QwasiLocationTypeGeofence:
if (state == QwasiLocationStateInside) {
// inside a geofence
}
else {
// now outside the geofence
}
break;
case QwasiLocationTypeBeacon:
if (state == QwasiLocationStateInside) {
// hit a beacon
}
else {
// left the beacon proximty
}
break;
default:
break;
}
}];
swift
//earlier in code
Qwasi.shared().on("location", selector: "onLocation:state:", target: self)
...
// location selector
func onLocation(location: QwasiLocation, state: QwasiLocationState) {
switch (location.type) {
case QwasiLocationType.Coordinate:
// This isnormal GPS update
break;
case QwasiLocationType.Geofence:
if (state == QwasiLocationState.Inside) {
// inside a geofence
}
else {
// now outside a geofence
}
break;
case QwasiLocationType.Beacon:
if (state == QwasiLocationState.Inside) {
// hit a beacon
}
else {
// left the beacon proximity
}
break;
default:
break;
}
}
Qwasi 支持基于键值的云数据存储系统。这些数据存储为成员或设备特定。键可以使用点分隔符表示的深对象路径。
每个设备都由一个成员记录支持。成员记录由一个 user_token 确定,并表示一个聚合记录。使用相同的 user_token 在设备之间提供数据可用性。
- (void)setMemberValue:(id)value forKey:(NSString*)key
success:(void(^)(void))success
failure:(void(^)(NSError* err))failure;
- (void)setMemberValue:(id)value forKey:(NSString*)key;
QwasiErrorSetMemberDataFailed
member.set_data
- (void)memberValueForKey:(NSString*)key
success:(void(^)(id value))success
failure:(void(^)(NSError* err))failure;
QwasiErrorGetMemberDataFailed
member.get_data
示例
Objective-C
[qwasi setMemberValue: @"35"
forKey: @"age"];
[qwasi memberValueForKey: @"age"
success:^(id value) {
NSLog(@"%@", value);
}
failure:^(NSError *err) {
}];
swift
qwasi.setMemberValue("35", forKey: "age")
qwasi.setMemberValue("35", forKey: "age", success: { () -> Void in
//handle success
}) { (error:NSError!) -> Void in
//handle failure
}
设备数据持久至设备,同时也针对成员特定。因此如果 user_token 发生变化,特定于设备的数据集也会发生变化。这使得多个用户可以共享设备,并拥有各自设备上的数据存储。
- (void)setDeviceValue:(id)value forKey:(NSString*)key
success:(void(^)(void))success
failure:(void(^)(NSError* err))failure;
- (void)setDeviceValue:(id)value forKey:(NSString*)key;
QwasiErrorSetDeviceDataFailed
device.set_data
- (void)deviceValueForKey:(NSString*)key
success:(void(^)(id value))success
failure:(void(^)(NSError* err))failure;
QwasiErrorGetDeviceDataFailed
device.get_data
示例
Objective-C
[qwasi setDeviceValue: @"hotrod99"
forKey: @"user.displayname"];
[qwasi deviceValueForKey: @"user.displayname"
success:^(id value) {
NSLog(@"%@", value);
}
failure:^(NSError *err) {
}];
swift
qwasi.setDeviceValue("hotrod99", forKey: "user.displayname")
qwasi.setDeviceValue("hotrod99", forKey: "user.displayname", success: { () -> Void in
//handle success
}) { (error:NSError!) -> Void in
//handle failure
}
使用 Qwasi API 和 SDK 可以向其他用户发送消息,这可以促进双向通信或聊天应用。Qwasi 并不明确支持此功能,所以大部分实现留给了开发者。您需要管理将您自己的 userTokens 映射到某些有用的数据,这些数据可以存储在所述的设备记录中。
- (void)sendMessage:(QwasiMessage*)message
toUserToken:(NSString*)userToken
success:(void(^)())success
failure:(void(^)(NSError* err))failure;
- (void)sendMessage:(QwasiMessage*)message
toUserToken:(NSString*)userToken;
QwasiErrorSendMessageFailed
message.send
示例接收者
Objective-C
// filter out our chat tags
[qwasi filterTag: @"chatMessage"];
[qwasi on: @"tag#chatMessage" listener: ^(QwasiMessage* message) {
// handle the message with the tag
NSString* displayName = [message.payload: @"from"];
NSLog(@"Got a message from %@", displayName);
}];
swift
//filter out our chat tages
qwasi.filterTag( "chatMessage")
qwasi.on("tag#chatMessage", selector: Selector("chatMessageHandler"), target: self)
...
func chatMessageHandler( message: QwasiMessage ){
let displayName = ["from" : message.payload]
NSLog("Got a message from \(displayName)");
}
示例发送者
Objective-C
QwasiMessage* welcome = [[QwasiMessage alloc] initWithAlert: @"You have a new message"
withPayload: @{ @"from": @"myusername" }
withPayloadType: nil
withTags: @[@"chatMessage"]];
[qwasi sendMessage: message toUserToken: @"anotheruser"];
swift
var welcome:QwasiMessage = QwasiMessage( alert: "You have a new message",
withPayload: [ "from": "myUserName"],
withPayloadType: nil,
withTags: [ "chatMessage"])
qwasi.sendMessage( welcome, toUserToken: "anotherUser" )