Iterable iOS SDK
iterable-ios-sdk
是 Iterable 的 iOS 客户端 Objective-C 实现,适用于 iOS 7.0 和更高版本。
在 Iterable 中设置推送集成
在开始使用 SDK 之前,您需要
- 设置您的应用程序以接收推送通知,并且
- 在 Iterable 中设置推送集成。这允许 Iterable 代表您与 Apple 的推送通知服务进行通信
如果您尚未这样做,您需要为您的应用程序启用推送通知。这可以通过在 Xcode 中切换目标的 Capabilities
下的 Push Notifications
来完成。您也可以在 Apple 的会员中心中的应用中心直接完成此操作;转到 Identifiers -> App IDs -> 选择您的应用程序
。您应该在 Application Services
下看到 Push Notifications
。点击 编辑
并启用 Push Notifications
。
您还需要为推送服务生成 SSL 证书和私钥。请参阅本节末尾的链接以获取更多信息。
一旦设置好您的APNS证书,请访问Iterable中的集成 -> 移动推送
。在创建集成时,您需要选择一个名称和一个平台。名称完全由您决定;当您在我们的SDK中使用registerToken
时,它将是appName
。平台可以是APNS
或APNS_SANDBOX
;它们分别对应于生产平台和沙盒平台。您的应用将根据是否使用开发证书或分发配置文件创建不同的令牌。
更多信息,请参阅
恭喜您,您已配置您的移动应用程序以接收推送通知!现在,让我们设置Iterable SDK...
自动安装(通过CocoaPods)
Iterable支持CocoaPods以方便安装。如果您还没有,可以通过运行Ruby
来安装它:
$ sudo gem install cocoapods
要将Iterable SDK添加到您的项目中,您需要将其添加到您的Podfile
中。如果您还没有Podfile
,您可以通过运行来创建一个:
$ pod init
要将Iterable pod添加到您的目标,编辑Podfile
并在目标下包含此行
pod 'IterableSDK'
现在,您需要告诉CocoaPods安装依赖项:
$ pod install
恭喜!您现在已将Iterable SDK导入到您的项目中!
ℹ 如果您的项目是用Swift
构建的,您将需要一个桥接头
。有关如何创建桥接头的更多信息,请参阅此处。
手动安装
在Artifacts
目录中,您可以找到编译好的静态库和头文件。要将它们添加到您的项目中...
- 将头文件添加到您的头文件搜索路径。在
Build Settings
->Search Paths
->Header Search Paths
下。输入存储SDK头文件的位置。您应该启用递归(并且它会在路径末尾添加**
)。 - 将您的项目与Iterable的SDK相关联。有两种方法可以做到这一点。
- 转到
Build Phases
->Link Binary With Libraries
并选择libIterable-iOS-SDK.a
,或 - 转到
Build Settings
->Search Paths
->Library Search Paths
,并输入libIterable-iOS-SDK.a
的位置。接下来,告诉您的项目在链接阶段查找Iterable-iOS-SDK
,请转到Build Settings
->Linking
->Other Linker Flags
,并添加-lIterable-iOS-SDK
- 转到
Build Settings
->Linking
->Other Linker Flags
,并添加-ObjC
。这是为了正确选择链接期间引用的NSData+Conversion.h
类别。更多信息请参见此处。
使用SDK
- 在应用启动时(
application:didFinishLaunchingWithOptions:
),初始化Iterable SDK
IterableConfig *config = [[IterableConfig alloc] init];
config.pushIntegrationName = "myPushIntegration";
[IterableAPI initializeWithApiKey:@"<your-api-key>" launchOptions:launchOptions config:config];
apiKey
应与Iterable项目中您项目的API键相对应。如果您想根据是否在DEBUG
模式下构建或在PRODUCTION
模式下构建指定不同的apiKey
,并将SDK指向相关Iterable项目。- 理想情况下,您将在
application:didFinishLaunchingWithOptions:
内部调用此方法并传递launchOptions
。这样,SDK将自动跟踪从远程Iterable推送通知启动的应用程序。 - 此方法为您创建一个单例
IterableAPI
。您可以通过[IterableAPI sharedInstance]
检索它。如果您稍后检索它,请确保您已先实例化它,或检查非nil的返回值。
- 一旦您知道用户的电子邮件(首选)或用户ID,请调用
setEmail:
或setUserId:
- 电子邮件:
[[IterableAPI sharedInstance] setEmail:@"[email protected]"];
- 用户ID:
[[IterableAPI sharedInstance] setUserId:@"userId"];
- 如果您在设置用户ID时,该用户ID必须已存在。
- 建议使用邮箱,因为这不需要在后端进行基于用户ID的额外查找。
-
注册远程通知
自iOS 10以来,首选方式是使用UserNotifications
框架。请参阅Apple文档中的Request Permission to Use Notifications和Registering Your App with APNs。- 通过
UNUserNotificationCenter
的requestAuthorizationWithOptions:completionHandler:
请求显示通知的授权。当您第一次调用此方法时,iOS将提示用户允许指定的交互。操作系统将通过提供的回调块异步通知您的用户选择。
对于iOS < 10,请调用UIApplication
的registerUserNotificationSettings:
- 调用
UIApplication
的registerForRemoteNotifications
方法将您应用注册为远程通知。 - 使用您的应用代理的
application:didRegisterForRemoteNotificationsWithDeviceToken:
方法接收用于发送远程通知所必需的设备令牌。使用application:didFailToRegisterForRemoteNotificationsWithError:
方法处理错误。
⚠ 如果未设置用户电子邮件或用户ID,则设备注册将失败。如果在应用启动后(即用户登录时)调用setEmail:
或setUserId:
,请确保再次调用registerForRemoteNotifications
以将设备注册为登录用户。 - 通过
-
将令牌发送到Iterable
使用SDK的- (void)registerToken:(NSData *)token
将令牌发送到Iterable
这将在pushIntegrationName
中指定的集成中注册令牌。如果你还提供了sandboxPushIntegrationName
,Iterable SDK将尝试从配置文件中确定APNS环境,并使用正确的集成(APNS或APNS_SANDBOX)注册设备。
设备令牌可能会更改,因此每次应用启动时,你的应用都需要重新注册并将接收到的令牌发送回你的服务器。不要在设备上缓存令牌;每次接收到令牌时都发送它。这是苹果推荐的做法;请参阅以下文档这里。特别是:⚠ 设备令牌可能会更改,因此每次应用启动时,你的应用都需要重新注册并将接收到的令牌发送回服务器。如果未能更新设备令牌,远程通知可能无法到达用户的设备。当用户将备份数据还原到新设备或计算机,或者重新安装操作系统时,设备令牌总是会更改。在将数据迁移到新设备或计算机时,用户必须先启动你的应用一次,然后远程通知才能发送到该设备。⚠ 永远不要缓存设备令牌;每次需要时都从系统中获取令牌。如果你的应用以前已注册远程通知,再次调用registerForRemoteNotifications方法不会产生任何额外的开销,iOS会立即将现有的设备令牌返回给应用程序代理。此外,iOS会在设备令牌更改时调用你的代理方法,而不仅仅是响应你的应用注册或重新注册。 -
处理推送交互 当用户点击通知或其中一个操作按钮时,系统会调用UNUserNotificationCenterDelegate的
userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
。将此调用传递到IterableAppIntegration
以跟踪推送打开事件并执行相关的操作(有关自定义操作和URL代理请见下文)。
整合所有内容
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// other setup tasks here....
// Initialize Iterable SDK
IterableConfig *config = [[IterableConfig alloc] init];
config.pushIntegrationName = "myPushIntegration_Prod";
config.sandboxPushIntegrationName = "myPushIntegration_Dev";
[IterableAPI initializeWithApiKey:@"YOUR API KEY" launchOptions:launchOptions config:config];
if (@available(iOS 10, *)) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
} else {
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
// Register for remote notifications.
}
// Handle remote notification registration.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)token {
[[IterableAPI sharedInstance] registerToken:token];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Error in registration for remote notifications. Error: %@", error);
}
// This is necessary for push notifications to work while the app is in foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
completionHandler(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound);
}
// Pass the notification response (tap on the notification or one of the buttons) to the Iterable SDK so it can track the push open event and perform the associated action
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
[IterableAppIntegration userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
// This method will be called when the notification is opened on iOS < 10
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[IterableAppIntegration application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
恭喜!你现在可以从Iterable向您的设备发送远程推送通知了!
Iterable通知
来自Iterable的所有通知都会在有效负载中包含一个名为itbl
的字段。此字段将包含Iterable使用的数据字典。您可以直接访问它,但应避免这样做,因为这些字段可能会更改。截至目前,字段包括:
campaignId
- 营销活动ID(在Iterable中)。对于证明和测试推送来说不相关。templateId
- 模板ID(在Iterable中)。对于测试推送来说不相关。messageId
- 消息ID(在Iterable)。isGhostPush
- 这是否是幽灵推送。请参阅下述有关卸载跟踪的部分。
卸载跟踪
Iterable 将通过您无需额外工作即可跟踪卸载。
这是通过在原始活动后一段时间(目前为12小时)发送第二次推送通知来实现的。如果我们收到设备令牌不再有效的反馈,我们将卸载分配给该设备,并将其归因于12小时内的最新活动。与后来的“幽灵”发送相比,“真实”的活动发送也可以触发记录卸载。在这种情况下,如果没有活动在归因期间,卸载仍然会被跟踪,但不会将其归因于任何活动。
这些“幽灵”通知将不会自动在设备上创建通知。事实上,除非您已启用后台模式,否则您的应用程序根本不会被通知。如果您希望应用程序接收并处理这些“幽灵”推送,您可以使用后台模式(这不会使通知显示出来;它只会让您的应用程序进行处理)。为此,请进入 Xcode 中的目标,然后转到 功能 -> 后台模式
并启用 后台获取
和 远程通知
。
启用后台模式后,您需要实现一个不同的方法来代替 application:didReceiveRemoteNotification:
;此方法是对 application:didReceiveRemoteNotification:fetchCompletionHandler: 的调用。此方法与 application:didReceiveRemoteNotification:
不同,无论您的应用程序是否在前台或后台运行,都会被调用。一旦完成,不要忘记用 UIBackgroundFetchResult
调用完成处理程序。有关后台模式通知的更多信息,请参阅 方法的文档 下的 讨论
。
禁用设备的推送通知
当用户登出时,您通常希望禁用该用户/设备的推送通知。这可以通过调用 disableDeviceForCurrentUser
来完成。请注意,只有当您之前调用过 registerToken
时,它才会尝试禁用该设备。
要重新启用该设备的推送通知,只需在用户重新登录时,通常调用 registerToken
即可。
应用内通知
要显示用户的InApp通知,请调用带有定义的ITEActionBlock
回调处理器的spawnInAppNotification
。当用户在通知上点击按钮时,将调用定义的处理程序,并传递InApp模板中定义的操作名称。
通过spawnInAppNotification
调用通知时,InApp将自动打开并记录按钮点击。使用spawnInAppNotification
,通知将被消耗并从用户的InApp消息队列中删除。如果您想保留队列上的消息,请考虑直接使用getInAppMessages
。如果您使用getInAppMessages
,您需要在回调处理器中手动管理InApp的打开。
跟踪和更新用户字段
可以使用track
函数跟踪自定义事件,并可以使用updateUser
函数修改用户字段。
深度链接
处理推送通知中的链接
推送通知和操作按钮可能附加有openUrl
操作。当指定URL时,SDK首先调用在您的IterableConfig
对象中指定的urlDelegate
。您可以使用此代理以与处理正常深度链接相同的方式来处理openUrl
操作。如果未设置代理或返回NO,SDK将使用该URL打开Safari。
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
// Initialize Iterable SDK
IterableConfig *config = [[IterableConfig alloc] init];
...
config.urlDelegate = self;
[IterableAPI initializeWithApiKey:@"YOUR API KEY" launchOptions:launchOptions config:config];
...
}
- (BOOL)handleIterableURL:(NSURL *)url context:(IterableActionContext *)context {
// Assuming you have a DeeplinkHandler class that handles all deep link URLs and navigates to the right place in the app
return [[DeeplinkHandler sharedInstance] handleUrl:url];
}
处理电子邮件中的链接
要使通用链接与电子邮件中的链接重写一起工作,您需要设置Iterable项目中的apple-app-site-association文件。更多说明请在此处:[设置iOS通用链接](https://support.iterable.com/hc/en-us/articles/115000440206-Setting-up-iOS-Universal-Links)
如果您已经有了 urlDelegate
(参见上文中的 处理推送通知中的链接 部分),那么可以通过在 UIApplicationDelegate
中的 application:continueUserActivity:restorationHandler: 调用 handleUniversalLink:
来为电子邮件深度链接使用相同的处理程序。
- (BOOL)application:(UIApplication *)application
continueUserActivity(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
// This will track the click, retrieve the original URL and call `handleIterableURL:context:` with the original URL
return [IterableAPI handleUniversalLink:userActivity.webpageURL];
}
或者,您可以调用 getAndTrackDeeplink
并附带一个回调来处理原始深度链接 URL。您可以使用此方法处理任何传入的 URL,因为它将执行回调而不更改非可迭代 URL 的 URL。
Swift
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
IterableAPI.getAndTrackDeeplink(userActivity.webpageURL!, callbackBlock: {
(originalURL) in
//Handle Original URL deeplink here
});
return true
}
Objective-C
- (BOOL)application:(UIApplication *)application
continueUserActivity(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
[IterableAPI getAndTrackDeeplink:iterableLink callbackBlock:^(NSString* originalURL) {
//Handle Original URL deeplink here
}];
return true;
}
富推送通知
推送通知可能包含带有图片、动画 GIF 或视频的媒体附件,并且即将推出的更新将提供创建操作按钮的方式。为了在您的应用中实现这一点,您需要创建一个通知服务扩展。更多说明请见:iOS 10 和 Android 中的富推送通知 - 媒体附件。
Iterable SDK 提供了一种处理媒体附件和操作按钮的实现,因此您只需从它继承即可。
Podfile
// If the target name for the notification extension is 'MyAppNotificationExtension'
target 'MyAppNotificationExtension' do
pod 'IterableAppExtensions'
end
NotificationService.h
#import <UserNotifications/UserNotifications.h>
#import <IterableAppExtensions/IterableExtensions.h>
@interface NotificationService : ITBNotificationServiceExtension
@end
附加信息
有关更多信息,请参阅我们的 设置指南。
同样,请参阅我们的 推送通知设置常见问题解答。
许可
麻省理工学院许可协议
查看LICENSE
想要贡献力量?
这个库是开源的,我们会查看拉取请求的!
更多详情请查看CONTRIBUTING