iNotify 1.5.6

iNotify 1.5.6

测试已测试
语言语言 Obj-CObjective C
许可证 zlib
发布最后发布2016年11月

Nick Lockwood维护。



iNotify 1.5.6

  • Nick Lockwood

目的

iNotify是一个简单的库,允许您将通知推送到用户的iPhone或Mac应用程序用户,当用户打开应用程序时,这些通知会弹出。与苹果内置的推送通知API不同,这些通知在应用程序未运行时不会出现(技术上,它们是由应用程序拉取而不是推送的),但它们在服务器端基础设施或配置方面需求非常少——您只需将一个文件放在公共URL上,并在需要时更新它。

这些通知包括一个标题、一条消息,以及可选的按钮,该按钮将用户发送到一个可以逐条消息指定的URL。

这些通知非常适合跨推广您的应用程序,或者通知用户他们可能错过的功能。

这些通知还可以用来通知用户关于新版本的信息,但对于此目的,您最好使用我们专门为此目的设计的iVersion库,它提供了更自动化的方法。iVersion和iNotify可以在同一项目中使用而不互相干扰。

请注意,本文件中的文档主要关注iPhone,但iNotify库应在Mac Cocoa应用程序上也同样有效地运行。

支持的iOS和SDK版本

  • 支持的构建目标 - iOS 10.1 / Mac OS 10.11 (Xcode 8.1, Apple LLVM编译器 8.0)
  • 最早支持的部署目标 - iOS 5.0 / Mac OS 10.7
  • 最早兼容的部署目标 - iOS 4.3 / Mac OS 10.6

注意:“支持”意味着库已经与这个版本进行了测试。“兼容”意味着库应在此iOS版本上运行(即它不依赖于任何不可用的SDK功能),但不再对此版本的兼容性进行测试,可能需要调整或修复错误才能正确运行。

ARC 兼容性

截至版本1.5.6,iNotify需要ARC。如果您要在非ARC项目中使用iNotify,只需将-fobjc-arc编译器标志添加到iNotify.m类中。要做到这一点,请转到您的目标设置中的构建阶段选项卡,打开编译源代码分组,在列表中双击iNotify.m,然后在弹出窗口中输入-fobjc-arc。

如果您要将整个项目转换为ARC,请注释掉iNotify.m中的#error行,然后在Xcode中运行编辑 > 重构 > 转换到Objective-C ARC... 工具,确保您希望使用ARC的所有文件都已被选中(包括iNotify.m)。

线程安全

iNotify使用线程来避免阻塞UI,但iNotify的所有外部接口都不是线程安全的,你不应该在主线程以外调用任何方法或设置任何iNotify属性。

安装

要将iNotify安装到你的应用程序中,将iNotify.h、.m和.bundle文件拖入你的项目。如果你不感兴趣本地化版本,可以省略(bundle)文件。

要启用iNotify,你需要实例化并配置iNotify,必须在应用程序启动完毕之前完成。最简单的方式是将iNotify配置代码添加到AppDelegate的initialize方法中,如下所示

+ (void)initialize
{
    //configure iNotify
    [iNotify sharedInstance].notificationsPlistURL = @"http://example.com/notifications.plist";
}

上述代码是使iNotify工作的最低配置,尽管你可能希望添加其他配置选项(以下有文档说明)。

你需要在某个公开的Web服务器上放置一个包含你的通知的plist文件。Plist的格式如下

<?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>2011/02/01</key>
    <dict>
        <key>Title</key>
        <string>Some notification title</string>
        <key>Message</key>
        <string>Some notification message</string>
    </dict>
    <key>2011/01/22</key>
    <dict>
        <key>Title</key>
        <string>Some other notification title</string>
        <key>Message</key>
        <string>Some other notification message</string>
        <key>ActionButton</key>
        <string>Find Out More...</string>
        <key>ActionURL</key>
        <string>http://example.com/somepage.html</string>
    </dict>
    ...
</dict>
</plist>

Plist的根节点是一个包含一个或多个键/字典对的字典。每个字典代表一个特定的通知消息。

每个值的键可以是不任何字符串,但最佳实践是使用YYYY/MM/DD格式的日期。这样做的原因是,消息将根据键进行反向字母顺序排序显示,因此,通过使用这样的日期,每次应用程序启动时,你的消息将按时间顺序(从新的开始)反向显示。如果你更喜欢显示最旧的,你可以配置iNotify按最旧显示。

如果你预计每天会发送多条消息,你可能需要调整命名方案,如添加时间或日期末尾的额外数字,或者采用不同的方案,例如使用递增的数字或字母序列作为每个消息的键。

一旦消息变得过时或不相关,你应该从plist中删除它们,以减少用户的下载时间。不要将所有消息无限期地保留在文件中。另外,请在删除旧的通知后不要重新使用消息键,因为已经查看过该键的消息的用户将永远看不到使用相同键的任何新消息。

每个值都应该是一个包含以下键的字典

  • 标题

促销消息的标题

  • 消息

通知消息的内容

字典还可以包含以下可选键

  • 操作URL

与通知相关的URL。如果省略操作URL,消息将不带操作按钮,只有OK按钮用于关闭消息。

注意操作URL可以被用来启动其他应用程序,或者通过指定自定义URL方案处理程序来在应用程序中触发行为。如果操作URL无法打开(因为应用程序未安装),则不会显示警报。

  • 操作按钮

打开操作URL的按钮标签。如果省略操作URL,则操作按钮值不被使用。如果包含操作URL,但省略操作按钮,操作按钮的文本将默认为iNotify配置常量中指定的值(默认为"更多信息...")。

  • 最小版本

应该在哪些最小应用程序版本上显示通知的版本。这对于指涉及特定应用程序版本中的功能的通告非常有用。例如,如果你忘记在应用程序的任何地方提及新功能,你可以使用此功能来通知用户有关最新版本中的新功能。

  • 最大版本

应显示通知的最大应用程序版本。这对于引用特定应用程序版本中的功能的通知很有用。例如,您可以使用此功能通知用户旧版应用程序的新版本可用(请注意,如果这是您使用iRate的唯一原因,您最好使用我们为该目的特别设计的iVersion库)。

配置

要配置iNotify,可以使用iNotify类的许多属性来改变行为和外观。大部分应该容易理解,但以下是一些关键属性:

@property (nonatomic, copy) NSString *notificationsPlistURL;

这是iNotify检查新通知消息的URL。为了测试目的,您可能希望在不同地址创建该文件的单独副本,并使用构建常量切换应用指向哪个版本。

@property (nonatomic, copy) NSString *applicationVersion;

应用程序的当前版本号。这用于与plist中的MinVersion和MaxVersion进行比较,以确定是否应显示特定的通知。这会自动设置为CFBundleShortVersionString(如果可用)或info.plist中的CFBundleVersion字符串,除非您了解自己在做什么,否则通常不建议更改它。

@property (nonatomic, assign) BOOL showOldestFirst;

此布尔值可以用来切换是否以最新通知优先(默认)或最旧通知优先显示。

@property (nonatomic, assign) BOOL showOnFirstLaunch;

当用户首次安装您的应用时,您可能不希望用弹出警报轰炸他们。使用此选项可以在应用程序第一次启动时禁用通知显示(默认设置为NO)。

@property (nonatomic, assign) float checkPeriod;

设置应用程序检查新通知消息的频率。这以天为单位衡量,但可以设置为分数值。设置更高的值以避免服务器流量过大。零值表示每次启动时都会检查。默认值为0.5天。

@property (nonatomic, assign) float remindPeriod;

用户选择“稍后提醒”选项后,应用程序等待提醒用户的时间长度。零值表示应用程序将在每次启动时提醒用户。请注意,此值将覆盖检查周期,所以一旦设置提醒,应用程序在提醒周期内不会检查通知,即使在此期间添加了更多通知。

@property (nonatomic, copy) NSString *okButtonLabel;

包含动作URL的消息的关闭按钮标签。

@property (nonatomic, copy) NSString *ignoreButtonLabel;

用户按下以关闭通知而无需访问相关动作URL的按钮标签。

@property (nonatomic, copy) NSString *remindButtonLabel;

用户按下以立即查看通知URL,但未来想要被提醒的按钮标签。如果不想显示提醒我按钮(例如,没有屏幕空间),则将其设置为nil。

@property (nonatomic, copy) NSString *defaultActionButtonLabel;

不指定通知plist时用于动作按钮标签的默认文本。

@property (nonatomic, assign) BOOL disableAlertViewResizing;

在iPhone上,iNotify包括一些逻辑来调整警报视图的大小,以确保在横屏模式下您的消息不会被截断。执行此操作的代码相当恶劣,因此如果您的警报文本非常短和/或您的应用仅在iPhone上以纵向模式运行,您可能希望将此属性设置为YES,这可能有助于使您的应用在未来iOS更新中更稳健。

@property (nonatomic, assign) BOOL onlyPromptIfMainWindowIsAvailable;

此设置仅适用于Mac OS。默认情况下,在Mac OS上,iNotify警报以主窗口上的对话框形式显示。某些应用程序没有主窗口,因此此方法不起作用。对于此类应用程序,将此属性设置为NO允许iNotify警报以常规模态窗口形式显示。

@property (nonatomic, assign) BOOL checkAtLaunch;

将此设置为“否”以禁用应用程序启动或从后台返回时自动检查通知。请注意,如果禁用自动检查,您仍然可以通过调用 checkForNotifications 方法手动触发检查。

@property (nonatomic, assign) BOOL debug;

如果设置为“是”,iNotify 将始终在应用程序启动时下载并在通知plist中显示下一未读消息,不受 checkPeriod 和 remindPeriod 设置的影响。启用调试后,仍未读的消息在所有消息都读取完毕后也将清除,以便在后续启动时从开始显示。

高级属性

如果默认的 iNotify 行为不符合您的要求,您可以通过使用高级属性、方法和委托来实施自己的行为。以下属性可以让您访问内部状态并覆盖它。

@property (nonatomic, copy) NSArray *ignoredNotifications;

一个数组,包含用户已经看到并选择忽略的通知的键。

@property (nonatomic, copy) NSArray *viewedNotifications;

一个数组,包含用户已经查看的通知的键。

@property (nonatomic, retain) NSDate *lastChecked;

上一次 iNotify 检查通知的日期。您可以将此与 checkPeriod 结合使用,以确定应用程序是否应该再次进行检查。

@property (nonatomic, retain) NSDate *lastReminded;

用户最后收到通知提醒的日期。您可以将此与 remindPeriod 结合使用,以确定应用程序是否应该再次进行检查。将此设置为 nil 以清除提醒延迟。

@property (nonatomic, assign) id<iNotifyDelegate> delegate;

您提供的实现 iNotifyDelegate 协议的对象。使用此对象来检测和/或覆盖 iNotify 的默认行为。默认为 App Delegate,所以如果您正在将 App Delegate 用作您的 iNotify 委托,则不需要设置此属性。

高级方法

这些可以与高级属性和委托结合使用,精确控制 iNotify 的行为。

- (NSString *)nextNotificationInDict:(NSDictionary *)dict;

此方法返回传递字典中最最近(或最旧,取决于 showOldestFirst 设置)的通知的键。您可以用此与 iNotifyDetectedNotifications 委托方法的 notifications 参数一起使用,以提取单个通知进行显示。

- (void)setNotificationIgnored:(NSString *)key;

这是一个方便的方法,用于将通知标记为已忽略,以便在未来的通知检查中不会显示。

- (void)setNotificationViewed:(NSString *)key;

这是一个方便的方法,用于将通知标记为已查看,以便在未来的通知检查中不会显示。

- (BOOL)shouldCheckForNotifications;

此方法执行正常的检查,以测试是否应该显示通知,包括如果可用,则调用 'iNotifyShouldCheckForNotifications' 委托方法。如果您已禁用 checkAtLaunch 并希望手动触发检查,同时仍然考虑检查周期、提醒周期等,这很有用。

- (void)checkForNotifications;

此方法将触发对新通知的新检查,忽略检查周期和提醒周期属性。

委托方法

iNotifyDelegate 协议提供了以下方法,用于拦截 iNotify 事件并覆盖默认行为。所有方法都是可选的。

- (BOOL)iNotifyShouldCheckForNotifications;

如果在满足所有检查条件后调用此方法,iNotify 将检查通知。如果返回 NO,则不会执行检查。如果您使用 checkForNotifications 方法手动触发检查,则不会调用此方法。

- (void)iNotifyDidNotDetectNotifications;

如果通知检查未检测到任何新通知(即未查看或忽略的通知),则调用此方法。

- (void)iNotifyNotificationsCheckDidFailWithError:(NSError *)error;

如果由于网络问题或通知 plist 文件缺失或损坏而导致通知检查失败,则调用此方法。

- (void)iNotifyDidDetectNotifications:(NSDictionary *)notifications;

如果检测到新的未查看或未忽略的通知,则调用此方法。notifications 参数是字典中的字典,每个条目表示单个通知(在结构上与通知 plist 中的内容相同)。

如果您只希望显示一条通知,请使用nextNotificationInDict方法来过滤出字典中最新的(或最早的,取决于showOldestFirst设置)通知。

要提取通知的个别字段,请使用在iNotify.h文件顶部定义的键常量。

- (BOOL)iNotifyShouldDisplayNotificationWithKey:(NSString *)key details:(NSDictionary *)details;

这将在显示通知警报之前立即调用。如果返回NO,则阻止显示警报。请注意,如果您确实返回NO,并且打算亲自实现警报,那么您需要根据用户响应手动更新lastChecked、lastReminded、ignoredNotifications和viewedNotifications属性。

- (void)iNotifyUserDidViewActionURLForNotificationWithKey:(NSString *)key details:(NSDictionary *)details;

当用户查看通知的动作URL时,将调用此方法。如果您想记录用户与iNotify的交互,这将很有用。只有当您使用标准的iNotify警报视图时,此方法才会调用;如果您提供了自定义的警报实现,则不会自动调用。

- (void)iNotifyUserDidRequestReminderForNotificationWithKey:(NSString *)key details:(NSDictionary *)details;

当用户请求再次提醒关于通知时,将调用此方法。如果您想记录用户与iNotify的交互,这将很有用。只有当您使用标准的iNotify警报视图时,此方法才会调用;如果您提供了自定义的警报实现,则不会自动调用。

- (void)iNotifyUserDidIgnoreNotificationWithKey:(NSString *)key details:(NSDictionary *)details;

当用户忽略通知时,将调用此方法。如果您想记录用户与iNotify的交互,这将很有用。只有当您使用标准的iNotify警报视图时,此方法才会调用;如果您提供了自定义的警报实现,则不会自动调用。

本地化

iNotify的默认字符串已本地化为英语、法语、德语、意大利语、西班牙语和日语,但是iNotify没有自动方法来自动本地化您的通知Plist文件中的内容。

要本地化通知本身,最简单的方法是为每种语言提供独立的通知Plist文件,每个文件都有唯一的URL。最简单的方法是将notificationsPlistURL包含在您的Localizable.strings文件中,如下所示

+ (void)initialize
{
    [iNotify sharedInstance].notificationsPlistURL = NSLocalizedString(@"http://example.com/notifications_en.plist", @"iNotify plist URL");
}

不建议您修改iNotify.bundle中的字符串文件,因为这会使更新到iNotify的新版本变得更加复杂。如果您确实想编辑这些文件或打开它们以便将密钥复制到您自己的字符串文件中,请注意iNotify字符串文件实际上已被编译为二进制plist,因此您需要在Xcode中打开它们,并使用“打开为”>“属性列表”选项,否则它们将显示为乱码。

如果您想添加额外的语言或替换所有内置字符串,最简单的方法是先从项目中移除iNotify.bundle,然后直接将iNotify键添加到您自己的Localizable.strings文件中。

如果您想覆盖一些本地化字符串但保留其他字符串不变,可以通过直接在代码中使用NSLocalizedString(...)设置任何或所有消息字符串的本地化值,例如

+ (void)initialize
{
    [iNotify sharedInstance].okButtonLabel = NSLocalizedString(@"OK", @"iNotify OK button");
    [iNotify sharedInstance].ignoreButtonLabel = NSLocalizedString(@"Ignore", @"iNotify ignore button");
    [iNotify sharedInstance].remindButtonLabel = NSLocalizedString(@"Remind Me Later", @"iNotify remind button");
    [iNotify sharedInstance].defaultActionButtonLabel = NSLocalizedString(@"More...", @"iNotify action button");
}

示例项目

第一次构建和运行示例项目时,它将显示一条关于iNotify的促销消息的警报。这是因为它已经下载了远程通知.plist文件,这是它找到的最新的消息。

关闭消息并退出应用程序。如果您重新启动,则每次启动应用程序都会显示一条新消息,直到Plist中的所有消息都已被查看,然后它们将再次循环。

通常,消息的展示频率会低一些,但由于调试选项在示例中设置为YES,因此通常会忽略正常的通知节流。如果您将调试设置为NO,则在应用程序每次启动时都不会看到警报,并且每个唯一的警报将只显示一次。

高级示例

高级示例展示了如何使用iNotifyDelegate方法实现一个完全定制的iNotify接口。自动检查被禁用,用户可以通过点击“检查通知”按钮来选择下载通知。

当点击时,应用会显示一个进度轮,然后在按钮下方打印通知。

此示例适用于Mac OS,但在iOS上也可以实现相同的功能。

发布说明

版本 1.5.6

  • 更新适用于iOS 10和Xcode 8

版本 1.5.5

  • 将ARCHelper宏移动到.m文件中,以避免影响其他类

版本 1.5.4

  • 修复了缓存策略,因此当应用运行时,通知不再在请求之间缓存

版本 1.5.3

  • 修复了可能在委托方法中设置的高级属性随后被iNotify覆盖的bug
  • 添加了disableAlertViewResizing选项(请参阅README获取详细信息)
  • 添加了对通知更新检查的明确60秒超时
  • 当在进行更新检查时关闭和重新打开iNotify时,它现在不再会启动多个下载线程

版本 1.5.2

  • 改进了UIAlertView的调整大小逻辑
  • 如果设备无法打开ActionURL,则不再显示Alert

版本 1.5.1

  • 添加了防止UIAlertView在横屏模式下收起的逻辑

版本 1.5

  • 包括法语、德语、意大利语、西班牙语和日语的本地化
  • 添加了iOS5中UIApplicationWillEnterForegroundNotification实现变化的解决方案
  • 除非另有指定,否则iNotify的委托默认为App委托
  • iNotify现在使用CFBundleShortVersionString来比较MaxVersion和MinVersion(如有)而不是CFBundleVersion
  • applicationVersion属性现在作为iNotify的属性公开,以便您可以重写它

版本 1.4.1

  • 添加了对ARC编译目标的自动支持
  • 现在需要Apple LLVM 3.0编译器目标

版本 1.4

  • 通知消息现在可以限制为特定的应用版本
  • 添加了额外的委托方法
  • 将disabled属性重命名为checkAtLaunch以提高清晰度

版本 1.3.2

  • 修复了忽略或查看过的通知继续出现的问题

版本 1.3.1

  • 修复了在iOS版本低于4.0时下载通知时崩溃的问题

版本 1.3

  • 添加了委托和额外的存取属性以实现自定义行为
  • 添加了高级示例项目以展示委托协议的使用
  • 添加了显式的ivar以支持i386(32位x86)目标

版本 1.2

  • 现在兼容iOS 3.x

版本 1.1

  • 配置不再涉及到修改iNotify.h文件
  • 现在可自动检测应用启动和切换事件
  • 修复了Mac代码路径中的bug
  • 现在包括Mac和iPhone演示
  • 本地化更简单

版本 1.0

  • 初始版本。