网络活动上/下/关闭的 iOS 事件/通知

Posted

技术标签:

【中文标题】网络活动上/下/关闭的 iOS 事件/通知【英文标题】:iOS event/notification for network activity up/down/off 【发布时间】:2013-01-22 09:35:37 【问题描述】:

当网络活动从无到启动(反之亦然)时,我希望我的 ios 应用程序有一个事件/回调。类似于 android 处理 onDataActivity() 的方式。我说的不是可达性,而是数据实际开始或停止传输的时间。

该应用不适用于 App Store,也不适用于越狱。我有一个类似的功能,可以通过使用

来检测屏幕何时开启/关闭
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
      NULL, // observer
      displayStatusChanged, // callback
      CFSTR("com.apple.iokit.hid.displayStatus"), // event name
      NULL, // object
      CFNotificationSuspensionBehaviorDeliverImmediately);

以及其他事件,例如

com.apple.springboard.hasBlankedScreen
com.apple.springboard.lockstate

现在我想知道是否存在数据何时开始或停止传输的事件?或者,如果有人可以向我指出可以通过上述方式监控的所有事件的完整列表的方向。

【问题讨论】:

【参考方案1】:

我在越狱的 iOS 5 iPhone 上同时监控了标准 Darwin 通知和 Core Telphony 通知。

我没有看到任何真正符合您要求的通知

有一些核心电话通知会出现,但不是在每次传输开始和结束时都会发出。看起来当数据服务连接时,可能会有一些通知,但同样,它们确实不是您所要求的:

kCTIndicatorRadioTransmitNotification
kCTRegistrationDataStatusChangedNotification

如果您想尝试自己监控所有Core Telephony 通知,您可以使用Core Telephony 框架和CT 通知中心:

-(void) registerCallback 
   id ct = CTTelephonyCenterGetDefault();
   CTTelephonyCenterAddObserver(ct,   // center
                                NULL, // observer
                                telephonyEventCallback,  // callback
                                NULL,                    // event name (or all)
                                NULL,                    // object
                                CFNotificationSuspensionBehaviorDeliverImmediately);
    

static void telephonyEventCallback(CFNotificationCenterRef center, void* observer, CFStringRef name, const void* object, CFDictionaryRef userInfo)

    //NSLog(@"telephonyEventCallback()");

    NSString* notifyName = (__bridge NSString*)name;
    if ([notifyName isEqualToString:@"kCTMessageReceivedNotification"])   // received SMS

     /* look for other notification names here */

在上述调用中,我将NULL 传递给CTTelephonyCenterAddObserver() 调用,该调用注册所有 通知。如果您知道要查找的内容,当然可以传递特定通知的名称,例如您为 com.apple.iokit.hid.displayStatus 发布的示例。

关于john.k.doe's option,您可以尝试在该属性上使用键值观察,以便在它更改时得到通知:

UIApplication* app = [UIApplication sharedApplication];
[app addObserver: self forKeyPath: @"networkActivityIndicatorVisible" options: NSKeyValueObservingOptionNew context: nil];

您的观察者回调在哪里:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
    if ([keyPath isEqualToString:@"networkActivityIndicatorVisible"]) 
        // process here
        NSLog(@"network activity indicator change!");
        BOOL active = [UIApplication sharedApplication].networkActivityIndicatorVisible;
    

我不确定 KVO 是否仍会在后台运行,这可能取决于您的应用如何管理后台运行。

但是,当然,这要求应用在访问网络时实际使用该属性,并非所有应用都这样做。不幸的是,Apple 甚至将该指标设置为第三方开发人员需要控制的东西。在 Android 和 BlackBerry 上,操作系统足够智能,可以知道何时发送/接收。

所以,这仍然只是你需要的一部分:(

【讨论】:

到目前为止,我已经尝试了您的代码/建议的第一部分。我收到一个编译错误,指出未声明 RTLD_LAZY。在下面的两行中还有一些警告“函数 'dlsym' 的隐式声明在 C99 中无效。”这真的适用于非越狱设备吗?在 cutnpaste.org/blog/ios-listen-incoming-sms 上找到类似的代码,但它指出您需要越狱才能工作。 我编辑了我的答案,添加了#include,您需要使用RTLD_LAZY 和其他动态库函数进行编译。正如我在答案中所说,我发布的代码是动态加载Core Telephony框架,并动态查找函数CTTelephonyCenterAddObserver()。你真的不得不那样做......我只是有一些确实需要动态加载的代码。您可以以正常方式将Core Telephony框架包含在您的项目中,直接调用CTTelephonyCenterAddObserver()函数即可。 @Sunkas,这确实适用于非越狱设备。我刚刚在我入狱的 iOS 6 iPhone 5 上试了一下,并收到了 CT 通知。您链接到的示例不仅仅用于收听通知。如果你想阅读收到的短信,你需要听那个通知,然后用 sqlite 打开 sms.db 文件来获取短信内容。第二部分需要越狱的手机。但是,对于您的问题,我只是建议您订阅通知。 我也只是将答案更改为使用动态加载,而只是正常使用Core Telephony API。您仍然需要将 CoreTelephony.framework 添加到您的项目中,并且您会收到编译警告,因为这些是私有 API。但是,它会起作用。 有时,不可能做你想做的事 :( 但是,现在你知道如何列出所有 CT 通知了。可能有一个私有 API 来解决这个问题,虽然我不会如果没有,会感到惊讶。如果有网络活动关闭/打开的回调,那么状态栏指示器可能会连接到那个。事实并不表明没有这样的私有 API。有可能Apple 不希望这样,因为它会显示 iOS 何时在后台进行小型网络调用,如果不是来自他们,用户可能不喜欢看到。【参考方案2】:

确实没有系统通知。

如果您正在谈论监控您自己的应用程序的活动,您显然可以控制它,并且应该能够将您知道的任何访问网络的呼叫括起来......

如果您正在谈论监视所有其他应用程序的活动,并且您愿意假定它们严格遵守 Apple 准则并打开/关闭状态栏中的网络活动状态指示器,您可以致电:

[[UIApplication sharedApplication] isNetworkActivityIndicatorVisible];

但这显然需要您以轮询方式执行此操作,最好在后台线程/GCD 队列上完成。然后您可以发布自己的通知,以便在您的应用中的其他地方看到。

【讨论】:

感谢您的回复!首先,我无法让该方法工作,它总是返回 false,即使右上角的小微调器正在旋转。也许是因为可能应用程序正在后台运行。其次,这个方法检查的Network Activity Indicator,由开发者调用吧?因此,如果正在使用网络但应用程序开发人员从未启动微调器,我仍然不会收到任何通知(使用 Nate 的观察者)? @Sunkas,没错。不幸的是,john 和我的解决方案都要求其他开发人员使用这个可选的 API。 Apple 的软件本身在使用方面非常好,但对于其他 3rd 方开发人员,它不会 100% 地指示网络活动。 @john.k.doe 感谢您的回答,我试图监控所有网络活动,我应该只监控我的... 不起作用。试图捕捉 AVPlayer 何时开始流式传输

以上是关于网络活动上/下/关闭的 iOS 事件/通知的主要内容,如果未能解决你的问题,请参考以下文章

如何在不关闭先前活动的情况下从通知中打开对话框样式的活动?

关闭的应用程序上的地理通知

当应用程序关闭或不活动时,如何处理 iOS 应用程序中的推送通知?

用户关闭应用程序时如何处理用户在 Xamarin iOS 上单击本地通知?

当该应用的通知关闭时,在 Android 上接收 Firebase 静默通知

在 socket.io 上设置高关闭超时是不是安全?