Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect at realtime the increase/decrease of cellular signal power in iOS

My app (it is an app store app) is able to connect via 3G/4G/LTE/Edge etc... however it cannot detect at realtime (via a callback perhaps) that the strength of the signal have been modified. For example: If I am connected with 4G and I am in the "corner" where the signal is EDGE or 2G I would like to disable some functionality. Also I would like to re-enable the functionality with the signal becomes 4G again.

I have seen the CTTelephonyNetworkInfo class and also those values are offered in the SDK

CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyGPRS          __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyEdge          __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyWCDMA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSDPA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSUPA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMA1x        __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORev0  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevA  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevB  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyeHRPD         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyLTE           __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);

but how can the app receive a notification if one of those values are active. I have some code that reads from the CTTelephoneNetworkInfo and the values I am taking back are correct, however this is done when I am calling the methods manually.

like image 262
cateof Avatar asked Apr 07 '16 15:04

cateof


People also ask

How do I check signal strength on iOS 15?

To see your signal strength represented by a number — and watch it change depending on how strong your signal is as you move around — go to your keypad and enter *3001#12345#.

How do I check signal strength on iOS 14?

After entering the Field Test app, tap on LTE (from the main menu on iOS 13 or the menu list on iOS 14) then tap on "Serving Cell Meas." The measurements that read "rsrp0" and "rspr1" are your cellular signal strength in decibel-milliwatts.


1 Answers

To detect cellular signal power I use CTRadioAccessTechnologyDidChangeNotification.

You can try this code :

import CoreTelephony

private var info: CTTelephonyNetworkInfo!

func createObserver() {
    self.info = CTTelephonyNetworkInfo();
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "currentAccessTechnologyDidChange",
            name: CTRadioAccessTechnologyDidChangeNotification, object: self.observerObject)
}

func currentAccessTechnologyDidChange() {
    if let currentAccess = self.info.currentRadioAccessTechnology {
        switch currentAccess {
        case CTRadioAccessTechnologyGPRS:
            print("GPRS")
        case CTRadioAccessTechnologyEdge:
            print("EDGE")
        case CTRadioAccessTechnologyWCDMA:
            print("WCDMA")
        case CTRadioAccessTechnologyHSDPA:
            print("HSDPA")
        case CTRadioAccessTechnologyHSUPA:
            print("HSUPA")
        case CTRadioAccessTechnologyCDMA1x:
            print("CDMA1x")
        case CTRadioAccessTechnologyCDMAEVDORev0:
            print("CDMAEVDORev0")
        case CTRadioAccessTechnologyCDMAEVDORevA:
            print("CDMAEVDORevA")
        case CTRadioAccessTechnologyCDMAEVDORevB:
            print("CDMAEVDORevB")
        case CTRadioAccessTechnologyeHRPD:
            print("HRPD")
        case CTRadioAccessTechnologyLTE:
            print("LTE")
        default:
            print("DEF")
        }
    } else {
        print("Current Access technology is NIL")
    }
}

I've tested it on my iphone by turning on/off airplane mode and I've noticed that sometimes I have to wait a bit more time for notification. So maybe the better way in your case will be just called info.currentRadioAccessTechnology and get the result when you need it. Of course, remember to remove observer when you don't need it anymore.

Apple documentation about this :

currentRadioAccessTechnology Discussion: The current radio access technology the device is registered with. May be NULL if the device is not registered on any network.

Additionaly, I do some research and I found an interesting answer which might help you.

Simple Obj-C version :

#import <CoreTelephony/CTTelephonyNetworkInfo.h>


CTTelephonyNetworkInfo *ctInfo = [CTTelephonyNetworkInfo new];
[[NSNotificationCenter defaultCenter] addObserverForName:CTRadioAccessTechnologyDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
    NSLog(@"current access radio access did change to : %@", ctInfo.currentRadioAccessTechnology); 
}];
like image 153
kamwysoc Avatar answered Sep 22 '22 21:09

kamwysoc