Measuring cellular signal strength
https://stackoverflow.com/questions/4954389/measuring-cellular-signal-strength
I am developing a non-appstore app for iOS. I want to read the cellular signal strength in my code.
I know Apple doesn't provide any API by which we can achieve this.
Is there any private API that can be used to achieve this? I have gone through the various threads regarding this issue but could not find any relevant info.
It is completely possible because there is an app in the app-store for detecting the carrier's signal strength.
ios iphone objective-c cocoa-touch
6,912113763
asked Feb 10 '11 at 7:17
140126
-
Does the value coming from VAFieldTest is accurate? – Dee Mar 18 '13 at 6:11
add a comment
6 Answers
9
I briefly looked at the VAFieldTest project located at Github.
There seems to be getSignalStrength()
and register_notification()
functions in Classes/VAFieldTestViewController.m that might be interesting to you as they call into CoreTelephony.framework
.
I am pretty confident that some of the used calls are undocumented in the CoreTelephony framework documentation from Apple and therefore private - any app in the AppStore must have slipped passed inspection.
answered Feb 10 '11 at 9:38
7,4852553
-
@Niels Castle How can I convert the signal strength that I got using VAFieldTest application to dBm? – DeeMar 18 '13 at 11:47
-
Follow the link to Github and you'll be able to interact directly with Vlad, the maintainer of VAFieldTest. – Niels Castle Mar 18 '13 at 15:01
-
Is it possible to get other parameters as well : RSCP (signal level), SC (Scrambling Code) and EcNo (Signal To Noise Ratio)? – luksmir May 17 '13 at 6:27
-
The project crashes almost instantly on iOS 9. – Raptor Dec 3 '15 at 10:37
-
Any idea how OpenSignal does their signal strength measurement ? They show the technology and signal strength on their home screen (tested on iOS 10), and the value is very accurate. – user5365075 Aug 19 '17 at 14:26
14
Get signalStreght IOS9:
UIApplication *app = [UIApplication sharedApplication];
NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
NSString *dataNetworkItemView = nil;
for (id subview in subviews) {
if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]])
{
dataNetworkItemView = subview;
break;
}
}
int signalStrength = [[dataNetworkItemView valueForKey:@"signalStrengthRaw"] intValue];
NSLog(@"signal %d", signalStrength);
25.1k85289
answered Dec 21 '15 at 5:44
864109
-
Works on iOS9 devices (not on simulators) – Alex Sorokoletov Jan 3 '16 at 17:01
-
Is this a private API github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/… UIKit is listed as public, but it seems like a private value. – chrisallick May 2 '16 at 20:51
-
Follow up. I built a small demo of this, created an app in itunes connect, and validated the store submission app archive. This isn't foolproof, but ostensibly the private API error would have been triggered? – chrisallickMay 4 '16 at 13:53
-
Crashes on iOS12 device, unfortunately – charmingToad Oct 12 '18 at 20:59
add a comment
10
It is not very hard.
- Link CoreTelephony.framework in your Xcode project
- Add the following lines where you need it
Code:
int CTGetSignalStrength(); // private method (not in the header) of Core Telephony
- (void)aScanMethod
{
NSLog(@"%d", CTGetSignalStrength()); // or do what you want
}
And you are done.
Update May 2016
Apple removed this opportunity.
answered Sep 18 '13 at 8:19
6,59094269
-
2
not run with IOS 8.3 – vualoaithu Apr 21 '15 at 1:55
-
1
it runs on iOS 9.1 , but value 0 is returned, no matter I use LTE or Wi-Fi. – Raptor Dec 3 '15 at 10:37
-
Doesn't work anymore. – OhadM Feb 17 '16 at 7:54
add a comment
5
To get signal streght in iOS 9 or above in Swift 3, without using the private API from CoreTelephony - CTGetSignalStrength()
. Just scouring the statusBar view.
func getSignalStrength() -> Int {
let application = UIApplication.shared
let statusBarView = application.value(forKey: "statusBar") as! UIView
let foregroundView = statusBarView.value(forKey: "foregroundView") as! UIView
let foregroundViewSubviews = foregroundView.subviews
var dataNetworkItemView:UIView!
for subview in foregroundViewSubviews {
if subview.isKind(of: NSClassFromString("UIStatusBarSignalStrengthItemView")!) {
dataNetworkItemView = subview
break
} else {
return 0 //NO SERVICE
}
}
return dataNetworkItemView.value(forKey: "signalStrengthBars") as! Int
}
Attention: If the status bar is hidden, the key "statusBar" will return nil.
answered Dec 15 '16 at 17:52
5114
-
It hurts my soul, but it meets the requirements: it works and it doesn't use any private APIs. Thank you! – Eliot Gillum Feb 1 '17 at 3:19
-
@EliotGillum does apple approves it? – user100 Mar 22 '17 at 10:52
-
key used does not exists in ios 10 – user100 Mar 22 '17 at 11:08
-
It uses private API : "value(forKey: "signalStrengthBars")" – dulgan May 11 '17 at 9:50
-
4
This no longer works in iOS 11 – Jas_meet Sep 28 '17 at 6:44
1
I haven't tested it, but apparently this is now a method of CTTelephonyNetworkInfo
instead of a global/static function.
The return type is id
, so I think you get either a NSDictionary
(as the _cachedSignalStrength
ivar implies) or an NSNumber
(as the old function implies).
id signalStrength = [[CTTelephonyNetworkInfo new] signalStrength];
This changed in iOS 8.3, as you can see from the commit.
Note that this is still not documented! So if your app will go in the App Store, take your precautions.
34.7k31175287
answered Jul 3 '15 at 15:50
9,73232638
-
2
signalStrength
returnsnull
in iOS 9 – Raptor Dec 3 '15 at 10:59 -
I am trying to get the cellular signal strength for iOS 9 but as mentioned above its returning 0. Using UIStatusBarSignalStrengthItemView does not work in background mode so it is of no use as i need to get signal strength in background. Please let me know if anybody is able to get the values. – iOS Dev Sep 20 '16 at 12:33
add a comment
0
Here's Lucas' answer converted to Xamarin, and tested on iOS 10.2.1:
var application = UIApplication.SharedApplication;
var statusBarView = application.ValueForKey(new NSString("statusBar")) as UIView;
var foregroundView = statusBarView.ValueForKey(new NSString("foregroundView")) as UIView;
UIView dataNetworkItemView = null;
foreach (UIView subview in foregroundView.Subviews)
{
if ("UIStatusBarSignalStrengthItemView" == subview.Class.Name)
{
dataNetworkItemView = subview;
break;
}
}
if (null == dataNetworkItemView)
return false; //NO SERVICE
int bars = ((NSNumber)dataNetworkItemView.ValueForKey(new NSString("signalStrengthBars"))).Int32Value;
answered Feb 1 '17 at 3:23
417413
-
haha, see you again! – User9527 Dec 12 '17 at 9:11
add a comment