Beacapp SDK for iOS 版本 2.3.1
��述
Beacapp中注册的内容在iOS上使用的SDK。
概要
BeacappSDKforiOS是iOS应用程序中集成Beacapp功能的SDK(软件开发工具包)。
BeacappSDKforiOS的主要功能如下。
-
BeacappSDK的激活:为了运行BeacappSDKforiOS,需要在每次应用启动时进行激活。激活是指访问Beacapp Web管理控制台(以下称为CMS),检查包含BeacappSDKforiOS的应用程序是否已在CMS中注册。如果应用程序未在CMS中注册或者CMS中提供的认证信息未正确设置,则被视为错误。此外,如果激活时终端的信号状态非常差(例如,飞行模式、无信号等),也可能被视为错误。
-
CMS设置的各类信息的下载:从CMS下载CMS设置的各类信息(如 beacon 的信息、事件触发条件的信息等)。这些信息的下载对于后续的beacon 捕获和事件触发是必要的。
-
beacon的捕获/停止捕获:执行beacon的捕获/停止捕获。BeacappSDKforiOS通过使用位置信息和验证Bluetooth状态来执行beacon的捕获。
-
事件的处理与触发:当检测到beacon时,BeacappSDKforiOS会自动判定该事件是否符合CMS中设置的条件。如果事件条件符合,则向包含BeacappSDKforiOS的应用程序发送通知。
运行环境
- Xcode6及以后的版本
- iOS8及以后的版本
CocoaPods)
SDK的导入(使用Podfile 中添加以下一行即可安装:
从版本1.3.0开始,请使用cocoapods 0.39.0以上版本。
pod "BeacappSDKforiOS"
-
注意:BeacappSDKforiOS不支持Bitcode。请更改Xcode的target设置。
[您的应用目标] - [构建设置] - [构建选项] - "启用Bitcode" -> 否
SDK的使用
-
导入头文件
#import <BeacappSDKforiOS/JBCPCore.h>
-
采纳Delegate(以下为设置于UIViewController的示例)
@interface ViewController : UIViewController<JBCPManagerDelegate>
-
创建JBCPMangaer实例
JBCPManager *manager = [JBCPManager sharedManager]; manager.delegate = self;
-
执行SDK激活操作
NSError *activateError = nil; BOOL activateResult = [manager initializeWithRequestToken:@"yourRequestToken" secretKey:@"yourSecretKey" options:nil error:&activateError];
-
从CMS获取最新的事件数据
NSError *eventError = nil; BOOL result = [manager startUpdateEvents:&eventError];
在激活获取事件的时候会调用以下委托。返回YES则执行事件数据的获取,返回NO则不执行事件数据的获取并结束处理。
- (BOOL)manager:(JBCPManager *)manager shouldUpdateEvents:(NSDictionary *)info{ if (![info[@"alreadyNewest"]boolValue]) { return YES; }else{ // YESを返すことによって、強制的にイベントデータの更新を実行することも可能です。 // NOを返しても、didFinishUpdateEventsは呼ばれます。 return NO; } } 最後に下記のデリゲートが呼ばれます。 - (void)manager:(JBCPManager *)manager didFinishUpdateEvents:(NSError *)error{ if(error){ // your error handling }else{ // do anything } }
-
开始监控基站。
NSError *scanError = nil; BOOL result = [manager startScan:&scanError];
-
CMS中设置的事件被检测到时,会调用以下的委托。
- (void)manager:(JBCPManager *)manager fireEvent:(NSDictionary *)event{ // do anything }
补充
-
JBCPManager激活或数据库生成失败时,startUpdateEvents: 或startScan: 等操作将无法执行。
-
事件数据的实际获取是异步处理。事件数据获取的API的BOOL值,当CMS事件数据的获取准备就绪时返回YES。请注意事件数据获取尚未完成。
-
在开始基站监控的时候推荐在事件数据获取过程完成后执行。在基站监控的时候执行事件数据获取过程,SDK会强制停止基站监控。即使事件数据获取处理及所有相关的处理都已完成,基站监控也不会自动恢复。
-
JBCPManagerDelegate可能在非主线程。如果需要在主线程中处理委托方法中的操作,需要判断是否在主线程。
if ([NSThread isMainThread]){ // main thread }else{ // not main thread dispatch_sync ( dispatch_get_main_queue(),^{ // do anything } ); }
-
如果想在后台检测基站,请在AppDelege或Root ViewController中实现JBCPManager和JBCPMangerDelegate。
-
BeacappSDKforiOS使用CLLocinitManager和CBPeripheralManager内部进行基站的检测。
-
在iOS8中使用BeacappSDKforiOS时,iOS8起位置信息服务的授权方式发生了变化。请在iOS应用的info.plist中添加以下密钥,并添加必要的应用说明。
键名 需要的版本 NSLocationAlwaysUsageDescription iOS8~ NSLocationAlwaysAndWhenInUsageDescription iOS11~ BeacappSDKfoiOS推荐使用AlwaysUse作为位置信息服务利用的授权种类
V1.4.0目前,在WhenInUse的情况下,Beacapp会自动显示位置信息服务使用许可申请警报
另外,为了与CMS通信,请按照以下AWS SDK的说明进行设置。
-
manager:fireEvent: 的事件信息处理方法样本 当事件被触发的时候,BeacappSDKforiOS会通知应用程序侧的委托方法中的事件信息的处理方法。
从(NSDictionary*)event中获取内容信息的方法
NSDictionary *actionContentDic = event[@"action_data"];
或者
NSDictionary *actionContentDic = [event objectForKey:@"action_data"];
这样就可以获取到CMS中设置的内容的字典对象,包含了内容种类的字典对象和内容信息。从actionContentDic对象中进一步获取正在CMS中设置的内容的种类和内容的方法如下。
NSString *type = actionContentDic[@"action"]; // type が URLもしくはimageの場合は、urlキーでコンテンツの内容を取得することができます。 if ([type isEqualToString:@"jbcp_open_url"] || [type isEqualToString:@"jbcp_open_image"]){ NSString *contentUrl = actionContentDic[@"url"]; } // typeがtextの場合は、textキーでコンテンツの内容を取得することができます。 else if([type isEqualToString:@"jbcp_open_text"]){ NSString *contentText = actionContentDic[@"text"]; } // typeがカスタムの場合は、key_valuesキーでCMSで設定したカスタムキーとバリューを取得することができます。 else if([type isEqualToString:@"jbcp_custom_key_value"]){ // Your Custom KeyValue can get Key => key_values NSDictionary *customKeyVaules = actionContentDic[@"key_values"]; }
-
示例代码 这是BeacappSDKforiOS一般处理流程的示例代码。
@interface ViewController () <JBCPManagerDelegate> @property (nonatomic, weak) JBCPManager *jbcpmanager; @end @implementation ViewController -(void)viewDidLoad{ [super viewDidLoad]; // YourCode } -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; NSError *error = nil; self.jbcpmanager = [JBCPManager sharedManager]; self.jbcpmanager.delegate = self; BOOL initRet = [self.jbcpmanager initializeWithRequestToken:@"yourRequestToken" secretKey:@"yourSecretKey" options:nil error:&error]; if (initRet) { BOOL updateEventRet = [self.jbcpmanager startUpdateEvents:&error]; if (updateEventRet) { // OK update start }else{ // NG update can't start } } } #pragma mark JBCPManagerDelegate -(BOOL)manager:(JBCPManager *)manager shouldUpdateEvents:(NSDictionary *)info{ if (![info[@"alreadyNewest"]boolValue]) { return YES; }else{ return NO; } return YES; } -(void)manager:(JBCPManager *)manager didFinishUpdateEvents:(NSError *)error{ if (!error) { NSError *startError = nil; if ([self.jbcpmanager startScan:&startError]) { }else{ NSLog(@"error %@",startError); } }else{ NSLog(@"error %@",error); } } -(void)manager:(JBCPManager *)manager fireEvent:(NSDictionary *)event { if ([NSThread isMainThread]) { // 処理 [self myBeaconEventUIShow:event[@"action_data"]]; } else { dispatch_sync ( dispatch_get_main_queue(), ^{ // 処理 [self myBeaconEventUIShow:event[@"action_data"]]; } ); } } -(void)myBeaconEventUIShow:(NSDictionary*)action_data{ // Your Code }
-
如果应用程序侧要使用CoreLocation
如果应用程序侧使用与本SDK不同的CLCircleRegion进行区域监控的话需要注意以下事项。
如果应用程序侧使用与本SDK不同的区域监控的话,根据CLLocationManager的规范,在监控本SDK中的iBeacon区域信息时,可能会触发CLLocationManagerDelegate的相关方法。
另外,iOS的应用程序中可观察的区域数量有限制。(最大20个)
本SDK中会按照Beacapp管理页面中登记的应用程序及相关的iBeacon UUID的模式数观测。(iBeacon需要3个UUID时,登记3个观测对象。)
请注意应用程序侧观测的区域数量与本SDK侧观测的iBeacon区域数量的区别。
- 保留事件检测日志时间戳顺序的方法 通过更改AWSSDK的处理内容,可以保持事件检测日志的时间戳顺序。按照以下步骤更改AWSSDK的处理内容。
- 经过验证的环境 AWSSDK的版本:2.5.2
- 注意:如果使用版本(2.5.2)以外的版本,可能会出现无法正常工作的情况。另外,即使添加了11的处理,根据操作环境,事件检测日志可能无法保留时间戳顺序。
11-1. 在创建的应用程序任意类(AppDelegate等)中导入以下头部文件。
#import <AWSKinesis/AWSKinesis.h>
#import <objc/runtime.h>
11-2. 在11-1中添加的相同类的导入部分直接后添加以下处理。
@implementation AWSKinesis(Swizzling)
- (AWSTask<AWSKinesisPutRecordOutput *> *)JBCPPutRecordSwizzling:(AWSKinesisPutRecordInput *)request{
NSError *error = nil;
NSString* partitionKey = [[JBCPManager sharedManager] getDeviceIdentifier:&error];
if(error == nil && partitionKey != nil){
request.partitionKey = partitionKey;
}
return [self JBCPPutRecordSwizzling:request];
}
- (AWSTask<AWSKinesisPutRecordsOutput *> *)JCBPPutRecordsSwizzling:(AWSKinesisPutRecordsInput *)request {
NSError *error = nil;
NSString* partitionKey = [[JBCPManager sharedManager] getDeviceIdentifier:&error];
if(error == nil && partitionKey != nil){
for(AWSKinesisPutRecordsRequestEntry* entry in request.records){
entry.partitionKey = partitionKey;
}
}
return [self JCBPPutRecordsSwizzling:request];
}
11-3. 在11-1中添加的相同类的实现部分(@implementation内)添加以下方法。
-(void)JCBPMethodSwizzling{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
{
Method from = class_getInstanceMethod(AWSKinesis.class, @selector(putRecord:));
Method to = class_getInstanceMethod(AWSKinesis.class, @selector(JCBPPutRecordSwizzling:));
if(from != nil && to != nil){
method_exchangeImplementations(from,to);
}
}
{
Method from = class_getInstanceMethod(AWSKinesis.class, @selector(putRecords:));
Method to = class_getInstanceMethod(AWSKinesis.class, @selector(JCBPPutRecordsSwizzling:));
if(from != nil && to != nil){
method_exchangeImplementations(from,to);
}
}
});
}
11-4. 在执行SDK激活操作前调用11-3中添加的方法(JCBPMethodSwizzling)。 [self JCBPMethodSwizzling];
11-5. 样本代码 这是添加到AppDelegate中的样本代码。 ・AppDelegate.h #import <UIKit/UIKit.h> #import <BeacappSDKforiOS/JBCPCore.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate,JBCPManagerDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
・AppDelegate.m
#import "AppDelegate.h"
#import <AWSKinesis/AWSKinesis.h>
#import <objc/runtime.h>
@implementation AWSKinesis(Swizzling)
- (AWSTask<AWSKinesisPutRecordOutput *> *)JCBPPutRecordSwizzling:(AWSKinesisPutRecordInput *)request{
NSError *error = nil;
NSString* partitionKey = [[JBCPManager sharedManager] getDeviceIdentifier:&error];
if(error == nil && partitionKey != nil){
request.partitionKey = partitionKey;
}
return [self JCBPPutRecordSwizzling:request];
}
- (AWSTask<AWSKinesisPutRecordsOutput *> *)JCBPPutRecordsSwizzling:(AWSKinesisPutRecordsInput *)request {
NSError *error = nil;
NSString* partitionKey = [[JBCPManager sharedManager] getDeviceIdentifier:&error];
if(error == nil && partitionKey != nil){
for(AWSKinesisPutRecordsRequestEntry* entry in request.records){
entry.partitionKey = partitionKey;
}
}
return [self JCBPPutRecordsSwizzling:request];
}
@end
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self performSelectorInBackground:@selector(initJBCPManager) withObject:nil];
return YES;
}
- (void)initJBCPManager{
// JBCPManagerインスタンスを取得する
JBCPManager *manager = [JBCPManager sharedManager];
manager.delegate = self;
[self JBCPMethodSwizzling];
// アクティベーションをする
NSError *activateError = nil;
[manager initializeWithRequestToken:@"yourRequestToken" secretKey:@"yourSecretKey" options:nil error:&activateError];
if (!activateError) {
// イベントをアップデートをする
NSError *eventError = nil;
[manager startUpdateEvents:&eventError];
} else {
NSLog(@"%@",activateError);
}
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
//AWSSDK処理内容を変更する。
-(void)JBCPMethodSwizzling{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
{
Method from = class_getInstanceMethod(AWSKinesis.class, @selector(putRecord:));
Method to = class_getInstanceMethod(AWSKinesis.class, @selector(JCBPPutRecordSwizzling:));
if(from != nil && to != nil){
method_exchangeImplementations(from,to);
}
}
{
Method from = class_getInstanceMethod(AWSKinesis.class, @selector(putRecords:));
Method to = class_getInstanceMethod(AWSKinesis.class, @selector(JCBPPutRecordsSwizzling:));
if(from != nil && to != nil){
method_exchangeImplementations(from,to);
}
}
});
}
#pragma mark - JBCPManagerDelegate
- (void)manager:(JBCPManager *)manager didFinishUpdateEvents:(NSError *)error{
if(error){
// 一旦何もしない
}else{
JBCPManager *manager = [JBCPManager sharedManager];
NSError *scanError = nil;
//VerboseModeをYESにする
[manager setVerboseMode:YES];
[manager startScan:&scanError];
}
}
- (void)manager:(JBCPManager *)manager fireEvent:(NSDictionary *)event{
NSDictionary *actionContentDic = [event objectForKey:@"action_data"];
NSString *type = actionContentDic[@"action"];
// typeがtextの場合は、textキーでコンテンツの内容を取得することができます。
if([type isEqualToString:@"jbcp_open_text"]){
NSString *contentText = actionContentDic[@"text"];
NSLog(@"event_text:%@",contentText);
}
}
@end
文档
各种API的文档等请访问这里。
创作者
许可
要使用BeacappSDKforiOS,必须同意Beacapp的使用条款。 无论通过何种方式下载BeacappSDKforiOS,都视为已同意Beacapp的使用条款。 您可以通过这里进行Beacapp的注册和使用条款的同意。
其他
-
BeacappSDKforiOS需要AWS SDK for iOS的版本2。
AWS SDK for iOS的版本2采用Apache 2.0许可证。 版本2的AWS SDK for iOS版权所有2014亚马逊公司或其关联公司。保留所有权利。 https://github.com/aws/aws-sdk-ios/blob/master/LICENSE
-
BeacappSDKforiOS需要FMDB。
FMDB版权所有(c) 2008-2014 Flying Meat Inc. https://github.com/ccgus/fmdb/blob/master/LICENSE.txt (https://github.com/ccgus/fmdb/blob/master/LICENSE.txt)