I am trying to listen to internet status change using the following code. This works fine with cocoa application but in daemon application, networkChangeHappend
method never gets called. Do I need to do anything different for daemon app? Or is there any other alternative to listen to internet state change in daemon application?
main.m
#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>
#import "ViewController.h"
int main(int argc, const char * argv[])
{
[NSThread detachNewThreadWithBlock:^{
[[ViewController sharedInstance] startOperation];
}];
[[NSRunLoop currentRunLoop] run];
return 0;
}
ViewController.h
#import <Foundation/Foundation.h>
@interface ViewController : NSObject
+ (instancetype _Nonnull )sharedInstance;
- (BOOL)startOperation;
@end
ViewController.m
#import "ViewController.h"
#import <SystemConfiguration/SystemConfiguration.h>
#include <arpa/inet.h>
@implementation ViewController
+ (instancetype)sharedInstance
{
static ViewController *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[ViewController alloc] init];
});
return sharedInstance;
}
- (instancetype)init
{
self = [super init];
if (self) {
[self registerNetworkChangeCallback];
}
return self;
}
//MARK: -
- (BOOL)startOperation {
//some stuff..
}
-(void)registerNetworkChangeCallback
{
struct sockaddr_in zeroAddress;
zeroAddress.sin_addr.s_addr = inet_addr("64.14.192.121");
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
void *info = (__bridge void *)(self);
SCNetworkReachabilitySetCallback ((SCNetworkReachabilityRef)defaultRouteReachability,(SCNetworkReachabilityCallBack)networkChangeHappend,info);
SCNetworkReachabilityScheduleWithRunLoop (
defaultRouteReachability,
CFRunLoopGetCurrent(),
kCFRunLoopDefaultMode
);
[Logger logString:@"registerNetworkChangeCallback"];
}
static void networkChangeHappend(
SCNetworkReachabilityRef target,
SCNetworkReachabilityFlags flags,
void *info
)
{
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
ViewController *viewController = (__bridge ViewController *)info;
(isReachable && !needsConnection) ? [viewController connected] : [viewController disconnected];
}
-(void)connected {
[Logger logString:@"Network connected"];
}
-(void)disconnected {
[Logger logString:@"Network disconnected"];
}
@end
You can use your *info pointer to give your callback a way to access the object you placed the Callback in.
and in your Callback accessing
"self"
again with.where
-(void)connected{}
and-(void)disconnected{}
could be methods of YourControllerClass