iOS event/notification for network activity up/dow

2019-05-14 16:54发布

问题:

I want a event/callback for my iOS app when the network activity goes from none to up (and the other way around). Similar to how Android does with onDataActivity(). I'm not talking about Reachability but when data actually starts or stops transmitting.

The app is not for App Store and not for jailbreak. I have got a similar functionality of detecting when the screen goes on/off working by using

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
      NULL, // observer
      displayStatusChanged, // callback
      CFSTR("com.apple.iokit.hid.displayStatus"), // event name
      NULL, // object
      CFNotificationSuspensionBehaviorDeliverImmediately);

along with other events such as

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

Now I wonder if there is a event for when data is started or stopped to transmit? Or if someone could point me the direction of a complete list of all events that can be monitored in the way above.

回答1:

I monitored both the standard Darwin notifications and the Core Telphony notifications on a jailbroken iOS 5 iPhone.

I did not see any notifications that really do what you want.

There are a few Core Telephony notifications that come out, but not on every transmit start and end. It looks like when the data service connects, there might be some notifications, but again, they really aren't exactly what you asked for:

kCTIndicatorRadioTransmitNotification
kCTRegistrationDataStatusChangedNotification

If you want to try monitoring all the Core Telephony notifications for yourself, you can use the Core Telephony framework, and the CT notification center:

-(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 */
}

In the above call, I pass NULL to the CTTelephonyCenterAddObserver() call, which registers for all notifications. You can of course pass the name of one particular notification if you know what you're looking for, like the example you posted for com.apple.iokit.hid.displayStatus.

Regarding john.k.doe's option, you might try using Key Value Observing on that property, to get notified when it changes:

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

where your observer callback is:

- (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;
    }
}

I'm not sure if KVO will still work in the background, and it might depend on how your app manages being backgrounded.

But, of course, that requires apps to actually use that property when they access the network, which not all of them do. It's unfortunate that Apple even made that indicator something that 3rd-party developers need to control. On Android and BlackBerry, the OS is smart enough to know when it's transmitting/receiving.

So, this is still only partly what you need :(



回答2:

there's really not a system Notification for this.

if you are talking about monitoring activity to/from your own app, you obviously have control of that, and should be able to bracket any calls you know to access the network …

if you are talking about monitoring activity to/from all other apps, and you are willing to presume that they are in strict compliance with Apple guidelines and turn on/off the network activity status indicator in the status bar, you can call:

[[UIApplication sharedApplication] isNetworkActivityIndicatorVisible];

but this obviously requires that you do so in a polling fashion, probably best done on a background thread / GCD queue. then you can post your own notification, to be seen elsewhere within your app.