2

ok so i want to detect weather the user has enabled hotspot/tethering or not in a iOS device. I can use private api's knowing it wont make it to the app store.

i was trying to go through private api's list/ runtime headers but there are too many to decide which might be helpful.

or if i could get to know where UIApplicationWillChangeStatusBarFrameNotification gets fired from in private api's(probably called for active call and activated hotspot etc)

i tried this detect personal hotspot and also used CaptiveNetwork but it only returns the connected wi-fi ssid and not the created hotspot.

any knowledge shared will be extremely helpful

Update: @creker

With the above code the compiler shows the error " SCDynamicStoreCreate is unavailable: not available on iOS. So i went into SCDynamicStore.h and changed the following

    SCDynamicStoreRef
SCDynamicStoreCreate            (
                    CFAllocatorRef          allocator,
                    CFStringRef         name,
                    SCDynamicStoreCallBack      callout,
                    SCDynamicStoreContext       *context
                    )               __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA);

to

    SCDynamicStoreRef
SCDynamicStoreCreate            (
                    CFAllocatorRef          allocator,
                    CFStringRef         name,
                    SCDynamicStoreCallBack      callout,
                    SCDynamicStoreContext       *context
                    )               __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_6_0);

now i am able to get the dictionary with the states 1022 and 1023. Just wanted to confirm by changing the file like this(not done before) will i have any problem in archiving build(or any other problem) other then the fact that we know this code won't make it to the app store

hemant
  • 1,771
  • 4
  • 31
  • 43

1 Answers1

10

Without Private APIs

You can detect active personal hotspot by enumerating network interfaces using C APIs. When hotpost is active and someone is connected to it there will be interface with bridge prefix. On my iPhone 5 it's bridge100. If hotspot is disabled or no one is connected to it that interfaces will not even be in the list.

C APIs will even return you IP address and subnet mask in that network.

That's what I'm using in my applications to detect active hotspot.

To get SSID you need [[UIDevice currentDevice] name] - personal hotspot SSID always matches device name.

With Private APIs

You can obtain all the information about personal hotspot using this code:

SCDynamicStoreRef sc = SCDynamicStoreCreate(NULL, CFSTR("com.apple.wirelessmodemsettings.MISManager"), NULL, NULL);
NSDictionary* info = (__bridge_transfer NSDictionary*)SCDynamicStoreCopyValue(sc, CFSTR("com.apple.MobileInternetSharing"));
CFRelease(sc);

info dictionary will look something like this when hotspot is active and has connections:

{
    Errnum = 0;
    ExternalInterfaces =     (
        "pdp_ip0"
    );
    Hosts =     {
        Current = 1;
        Max = 5;
        MoreAllowed = 1;
        Type =         {
            AirPort = 0;
            Bluetooth = 0;
            Ethernet = 0;
            "USB-Ethernet" = 1;
        };
    };
    InternalInterfaces =     (
        bridge100
    );
    Reason = 0;
    State = 1023;
    Version = 2;
} 

When hotspot is active but there are no connections:

{
    Errnum = 0;
    ExternalInterfaces =     (
    );
    Hosts =     {
        Current = 0;
        Max = 5;
        MoreAllowed = 1;
        Type =         {
            AirPort = 0;
            Bluetooth = 0;
            Ethernet = 0;
            "USB-Ethernet" = 0;
        };
    };
    InternalInterfaces =     (
    );
    Reason = 0;
    State = 1023;
    Version = 2;
}

When hotspot is not active:

{
    Errnum = 45;
    ExternalInterfaces =     (
    );
    Hosts =     {
        Current = 0;
        Max = 5;
        MoreAllowed = 1;
        Type =         {
            AirPort = 0;
            Bluetooth = 0;
            Ethernet = 0;
            "USB-Ethernet" = 0;
        };
    };
    InternalInterfaces =     (
    );
    Reason = 0;
    State = 1022;
    Version = 2;
}

State key will be equal to 1023 when hotspot is active regardless of active connections. I don't know whether that value contains bit-flags or not. iOS is actually checking if value is equal to 1023.

SCDynamicStore APIs are from public SystemConfiguration framework but marked as not available on iOS platform. That means all the headers are there, you just need to copy definitions without __OSX_AVAILABLE_STARTING macro.

You can even observe changes to that setting - you can specify a key which value you want to observe. Read Apple documentation for implementation details.

UPDATE

So i went into SCDynamicStore.h and changed the following

I wouldn't do that. It shouldn't cause any problems but for me changing SDK headers is not a good solution. I suggest the following. Don't include the framework headers. Make your own header where you copy all the methods you need with __OSX_AVAILABLE_STARTING changed or removed.

creker
  • 9,400
  • 1
  • 30
  • 47
  • How is that different from the OP's "detect personal hotspot" link? – Jesse Rusak Jul 04 '15 at 16:24
  • @JesseRusak, I gave a full answer to his question including SSID of the hotspot. The code in the link uses wrong interface name. As you can see, looking for `bridge0` is wrong - on newer devices it's called `bridge100`. We need to look just for the prefix `bridge`. – creker Jul 04 '15 at 17:38
  • great. it worked. i am also getting bridge100 as of now. but i was still wondering if i could get the hotspot active status irrespective of the fact that no one has connected to that hotspot yet? – hemant Jul 05 '15 at 06:52
  • @creker i have updated the question, have another query so we can hopefully close it – hemant Jul 05 '15 at 13:24
  • Hi,I try to using your code to get the hotspot info. But I get below error. 'SCDynamicStoreCreate' is unavailable: not available on iOS. And other error below 'SCDynamicStoreCopyValue' is unavailable: not available on iOS. Have any method to resolve above problem? My try these code in xcode6.4.iOS SDK 8.4. Thank you very much. – dickfala Jul 23 '15 at 14:02
  • @dickfala, I mentioned that in my answer. – creker Jul 23 '15 at 18:35
  • @creker , thank for your response. I'm not very understand. Can you explain how to do and changed you mention detail method ? You meaning we should copy the SCDynamicStore.h and copy into to project and changed or delete manually?I try to delete have show __OSX_AVAILABLE_STARTING method?But they are still not found the SCDynamicStoreCreate .sorry, I'm stupid. But I really want to achieve the function. Can you help me ,please.thanks – dickfala Jul 24 '15 at 09:51
  • Hi @creker, I had post my complete problem at the http://stackoverflow.com/questions/31621847/ios-how-to-detect-hotspot-turn-on-in-ios8 Can you help me? thank you. – dickfala Jul 25 '15 at 01:12
  • 1
    How to "enumerating network interfaces using C APIs", could you please post the code? – DàChún Sep 05 '17 at 13:22
  • 1
    found it, thanks: https://stackoverflow.com/questions/30748480/swift-get-devices-ip-address – DàChún Sep 05 '17 at 13:53