I would like to know if some of theses functions are possible with the IOS sdk.
In background process:
to catch
-the available memory space on the ipad
-number of cpu
-ram size of the ipad
-type of screen
-langage of the user
-HostName
-Ip adress
-bluetooth adress
-name of the ipad
-IOS version
-Installed apps on the Ipad
-memory used by our app
To catch all these data in background and to send it to a web service. Do you think all this, is possible and allowed by the ios sdk ?
Thank you
Most of it is, check the UIDevice class and the folowing questions:
iPhone/iPad/OSX: How to get my IP address programmatically?
How to get iOS device MAC address programmatically
You can send this info to your webservice without notifying the user, but it's not a nice thing to do.
The available memory space on the ipad = Maybe not tried it but don't see why not
Number of CPU = YES
Ram size of the ipad = YES
Type of screen = Not sure what you mean
Language of the user = YES (CAN NOT send in background to webservice without users permission)
HostName = Not sure what you mean (Whilst I don't know what you mean I can see this not be allowed to be sent without the users permission)
IP address = YES (CAN NOT send in background to webservice without users permission)
bluetooth address = Not sure what you mean
Name of the ipad = YES (CAN NOT send in background to webservice without users permission)
iOS version = YES
Installed apps on the Ipad = NO
Memory used by our app = Maybe never tried but don't see why not
Basically any personal information about the user you can't send without the users permission.
what you can get, if app is in foreground are below.
1) available memory space on the ipad
2) type of screen andlangage of the user
3) name of the ipad and iOS version
left-over you can't fetch even if app is in foreground.
apple doesn't allow to run app in background to prevent battery consumption, even if, allow then for around 20-30 seconds, when app goes in background from foreground.
[UIDevice currentDevice].model
[UIDevice currentDevice].systemVersion
[UIDevice currentDevice].name
[UIDevice currentDevice].systemName
[UIDevice currentDevice].localizedModel
[UIDevice currentDevice].userInterfaceIdiom
[UIDevice currentDevice].identifierForVendor
[[UIDevice currentDevice] platformType]
[[UIDevice currentDevice] platformString]
Related
I'm writing an app that optionally allows you to send an SMS to a list of users. The app currently detects whether the device allows the sending of text messages using MFMessageComposeViewController.canSendText() and only displays the "Send SMS" button when the result is true.
Today, one of my users complained that when he hit the button on his Wifi-only iPad, nothing happened. As it turns out, canSendText() also returns true if the iOS device has the iMessage capability turned on, even if SMS is not supported. Turning the iMessage capability off in the iOS setting properly disables the "Send SMS" button.
The problem with sending the message via iMessage is that some recipients will have iMessage turned on and thus will receive the text message. But for the recipients without iMessage (it may be turned off or they may not be using an Apple device in the first place), those messages will not arrive. (When the MFMessageComposeViewController eventually comes up, those addresses are marked in red. But my average user is not going to understand that this means the message will not delivered.)
Does anybody know of a reliable method that tests for SMS capability specifically, not just for text messages (SMS, iMessage and MMS) in general?
As far as I know devices with iOS 5+ will return TRUE for MFMessageComposeViewController.canSendText() as they are capable of iMessage
So I assume you only need to send text if SIM card is installed on device.
But there is no way to detect if SIM card is installed on device. Still you can use workaround like :
#import<CoreTelephony/CTCallCenter.h>
#import<CoreTelephony/CTCall.h>
#import<CoreTelephony/CTCarrier.h>
#import<CoreTelephony/CTTelephonyNetworkInfo.h>
CTTelephonyNetworkInfo* info = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier* carrier = info.subscriberCellularProvider;
NSString *mobileCountryCode = carrier.mobileCountryCode;
NSString *carrierName = carrier.carrierName;
NSString *isoCountryCode = carrier.isoCountryCode;
NSString *mobileNetworkCode = carrier.mobileNetworkCode;
NSLog(#"\n %# \n %# \n %# \n %#", mobileCountryCode, carrierName, isoCountryCode, mobileNetworkCode);
Here, carrierName will return name when SIM card is present OR last use SIM card info. But others will be null if there is no SIM card installed.
I want to show an alert view when my iOS app is in the background (and it's using location).
For example, the Uber Partner (Driver) app shows an alert and plays a sound even when:
I have turned off notifications!
My iPhone is in Silent mode!
I am aware of the local notifications approach and it doesn't work if the user turns off/ changes the Notifications in Settings. I am looking for something different.
Actions performed to reach the above state:
Go online on Uber Partner App (you are the driver!)
Disable Notifications for the app in Settings
Move the app to background and wait for a Ride Request
After some time, a ride Request is popped up as an Alert view and a sound is played in the background
Of course, silent remote notifications can be tapped in by the app using the didReceiveRemoteNotification: fetchCompletionHandler: API even if the user disables Notifications in Settings. But, how the alert is popped up, that's what I am trying to find out.
I would imagine that Uber has some special permissions or uses some private API that allow them to achieve this behavior without using local notifications. While I don't know how Uber implemented this in their partner app, I can talk a little bit about how alerts work on the home screen.
SpringBoard is the singleton class that manages the SpringBoard application (SpringBoard.app), the application launcher for the iPhone. SpringBoard doesn't use the standard UIAlertView/UIAlertController classes, since they don't participate in the SpringBoard-wide alert system. iOS 5 introduced SBAlertItem the which is used to display UIAlertViews on SpringBoard (Battery Notification Alerts, Sim Unlock Alert, etc.). Apple uses SBAlertItem for their lock and home screen alerts, I'll be working on the assumption that Uber is using an SBAlertItem for this answer.
SBAlertItem has a protected ivar UIAlertView *_alertSheet. Assuming this acts as a normal UIAlertView, you should be able to change the properties on this alert to fit your needs. I would also read through saurik's Cydia Substrate project, specifically MobileSafety.mm to see some use cases. I've also found noweibogoodsleep which provides an example of using SBAlertItem on the SpringBoard.
I've also found SBUserNotificationAlert, a subclass of SBAlertItem. This appears to have more methods to facilitate alert customization that may fit your needs better than the standard SBAlertItem.
I realize hooking into private APIs is probably not what you were expecting when asking this question. Since I don't know how Uber works, I can only provide an answer from my personal experience working with the runtime and jailbroken devices.
After some static analysis of the binary, it became clear that they are not using PKPushRegistry (VOIP), undocumented NSNotificationCenter calls or SBAlertItem.
Took a little while to find it, but they are actually using CFUserNotification for the alerts. The class is documented for Mac, but private for iOS.
I found the usage by doing this:
nm -u ~/Downloads/Payload/UberDriver.app/UberDriver | grep CFUserNotification
The output is:
_CFUserNotificationCancel
_CFUserNotificationCreate
_CFUserNotificationCreateRunLoopSource
_kCFUserNotificationAlertHeaderKey
_kCFUserNotificationAlertMessageKey
_kCFUserNotificationAlertTopMostKey
_kCFUserNotificationAlternateButtonTitleKey
_kCFUserNotificationDefaultButtonTitleKey
_kCFUserNotificationSoundURLKey
If I grep for PKPushRegistry or for SBAlertItem, both return no results.
Can use the class by importing this file to your project.
UPDATE
I have 'working' code, however it immediately calls the callback function (responseFlags set to kCFUserNotificationCancelResponse) without showing the alert..
I am using the same keys and calls as the Uber app (compare code below to list above), so there must be something extra. Will keep looking.
#import "CFUserNotification.h"
#interface AppDelegate ()
#property (nonatomic) CFRunLoopSourceRef runLoopSource;
#property (nonatomic) CFUserNotificationRef notification;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
SInt32 error;
NSDictionary *keys = #{(__bridge NSString*)kCFUserNotificationAlertHeaderKey: #"Hello",
(__bridge NSString*)kCFUserNotificationAlertMessageKey: #"World",
(__bridge NSString*)kCFUserNotificationAlertTopMostKey: #YES,
(__bridge NSString*)kCFUserNotificationDefaultButtonTitleKey: #"asdf",
(__bridge NSString*)kCFUserNotificationAlternateButtonTitleKey: #"asdf",
};
self.notification = CFUserNotificationCreate(NULL, 10, kCFUserNotificationPlainAlertLevel, &error, (__bridge CFDictionaryRef)keys);
self.runLoopSource = CFUserNotificationCreateRunLoopSource(NULL, self.notification, NotificationCallback, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), self.runLoopSource, kCFRunLoopCommonModes);
return YES;
}
void NotificationCallback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags) {
NSLog(#"got response: %lu", responseFlags);
}
Your question missed the most important part regarding the "Uber Partner" app that would make things a lot clearer. The "Uber Partner" app is an Enterprise app and is not restricted to the Appstore guide lines.
it didn't got any special permissions like other answers suggested.
It is possible to display an alert view using SBAlertItem regardless of Sound \ Notification settings but if your end goal is to make it to the appstore, unfortunately, your app will be rejected for using private API.
I want to show an alert view when my iOS app is in the background (and it's using location).
For example, the Uber Partner (Driver) app shows an alert and plays a sound even when:
I have turned off notifications!
My iPhone is in Silent mode!
I am aware of the local notifications approach and it doesn't work if the user turns off/ changes the Notifications in Settings. I am looking for something different.
Actions performed to reach the above state:
Go online on Uber Partner App (you are the driver!)
Disable Notifications for the app in Settings
Move the app to background and wait for a Ride Request
After some time, a ride Request is popped up as an Alert view and a sound is played in the background
Of course, silent remote notifications can be tapped in by the app using the didReceiveRemoteNotification: fetchCompletionHandler: API even if the user disables Notifications in Settings. But, how the alert is popped up, that's what I am trying to find out.
I would imagine that Uber has some special permissions or uses some private API that allow them to achieve this behavior without using local notifications. While I don't know how Uber implemented this in their partner app, I can talk a little bit about how alerts work on the home screen.
SpringBoard is the singleton class that manages the SpringBoard application (SpringBoard.app), the application launcher for the iPhone. SpringBoard doesn't use the standard UIAlertView/UIAlertController classes, since they don't participate in the SpringBoard-wide alert system. iOS 5 introduced SBAlertItem the which is used to display UIAlertViews on SpringBoard (Battery Notification Alerts, Sim Unlock Alert, etc.). Apple uses SBAlertItem for their lock and home screen alerts, I'll be working on the assumption that Uber is using an SBAlertItem for this answer.
SBAlertItem has a protected ivar UIAlertView *_alertSheet. Assuming this acts as a normal UIAlertView, you should be able to change the properties on this alert to fit your needs. I would also read through saurik's Cydia Substrate project, specifically MobileSafety.mm to see some use cases. I've also found noweibogoodsleep which provides an example of using SBAlertItem on the SpringBoard.
I've also found SBUserNotificationAlert, a subclass of SBAlertItem. This appears to have more methods to facilitate alert customization that may fit your needs better than the standard SBAlertItem.
I realize hooking into private APIs is probably not what you were expecting when asking this question. Since I don't know how Uber works, I can only provide an answer from my personal experience working with the runtime and jailbroken devices.
After some static analysis of the binary, it became clear that they are not using PKPushRegistry (VOIP), undocumented NSNotificationCenter calls or SBAlertItem.
Took a little while to find it, but they are actually using CFUserNotification for the alerts. The class is documented for Mac, but private for iOS.
I found the usage by doing this:
nm -u ~/Downloads/Payload/UberDriver.app/UberDriver | grep CFUserNotification
The output is:
_CFUserNotificationCancel
_CFUserNotificationCreate
_CFUserNotificationCreateRunLoopSource
_kCFUserNotificationAlertHeaderKey
_kCFUserNotificationAlertMessageKey
_kCFUserNotificationAlertTopMostKey
_kCFUserNotificationAlternateButtonTitleKey
_kCFUserNotificationDefaultButtonTitleKey
_kCFUserNotificationSoundURLKey
If I grep for PKPushRegistry or for SBAlertItem, both return no results.
Can use the class by importing this file to your project.
UPDATE
I have 'working' code, however it immediately calls the callback function (responseFlags set to kCFUserNotificationCancelResponse) without showing the alert..
I am using the same keys and calls as the Uber app (compare code below to list above), so there must be something extra. Will keep looking.
#import "CFUserNotification.h"
#interface AppDelegate ()
#property (nonatomic) CFRunLoopSourceRef runLoopSource;
#property (nonatomic) CFUserNotificationRef notification;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
SInt32 error;
NSDictionary *keys = #{(__bridge NSString*)kCFUserNotificationAlertHeaderKey: #"Hello",
(__bridge NSString*)kCFUserNotificationAlertMessageKey: #"World",
(__bridge NSString*)kCFUserNotificationAlertTopMostKey: #YES,
(__bridge NSString*)kCFUserNotificationDefaultButtonTitleKey: #"asdf",
(__bridge NSString*)kCFUserNotificationAlternateButtonTitleKey: #"asdf",
};
self.notification = CFUserNotificationCreate(NULL, 10, kCFUserNotificationPlainAlertLevel, &error, (__bridge CFDictionaryRef)keys);
self.runLoopSource = CFUserNotificationCreateRunLoopSource(NULL, self.notification, NotificationCallback, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), self.runLoopSource, kCFRunLoopCommonModes);
return YES;
}
void NotificationCallback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags) {
NSLog(#"got response: %lu", responseFlags);
}
Your question missed the most important part regarding the "Uber Partner" app that would make things a lot clearer. The "Uber Partner" app is an Enterprise app and is not restricted to the Appstore guide lines.
it didn't got any special permissions like other answers suggested.
It is possible to display an alert view using SBAlertItem regardless of Sound \ Notification settings but if your end goal is to make it to the appstore, unfortunately, your app will be rejected for using private API.
Problem: using UDID is deprecated - we cannot use it anymore.
There are some solutions on the net: generate GUID and store it in the "safe place", iCloud, IdentifierForVendor starting with iOS6, OpenUID, SecuredID and so on...
Request:
I need to have a unique identifier of the Device to store user data on our server.
Question:
Can I use deviceToken of Push Notification as a unique identifier?
What are the pros and cons of this idea?
(-) user can disable push notifications
(+) unique number
(+) supported in all iOS
This is a terrible idea, the token can change if the user changes device or for some other unknown reason.
The user can have multiple devices
If the user reinstalls the app they can get an other token
It's not 100% that the user will keep the same token.
And most important of all: You are identifying devices not users!
One solution is to generate a UUID and save it in the user keychain where you retrieve it. But this can also be removed if the user clear the device.
You best option is to allow the user to login with an account, which that can create. Then you can combine this with the UUID in the keychain.
You should use identifierForVendor. The deviceToken for push notification is unique, but CAN change.
The token can change if the user reset the device, for unique device identifying you can use the following code
float currentVersion = 6.0;
NSString *udid = nil;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= currentVersion)
{
//below code is taken from the Apple Sample code, to check you can download the files
https://developer.apple.com/library/ios/releasenotes/StoreKit/IAP_ReceiptValidation
// OR
http://developer.apple.com/library/ios/releasenotes/StoreKit/IAP_ReceiptValidation/VerificationController.zip (line number 319)
udid = [UIDevice currentDevice].identifierForVendor.UUIDString;
}
else
{
//may cause apple rejection
udid = [UIDevice currentDevice].uniqueIdentifier;
//i think we can use the below link for ios5 or below but not sure it may accept or reject
https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5
}
//just saw a link which may help you better and have a look at image
http://www.doubleencore.com/2013/04/unique-identifiers/
can someone suggest the best way to persist the unique id even after reinstall app, delete app or system restart or system boot or factory reset
Is there any way to get own phone number by standard APIs from iPhone SDK?
At the risk of getting negative marks, I want to suggest that the highest ranking solution (currently the first response) violates the latest SDK Agreement as of Nov 5, 2009. Our application was just rejected for using it. Here's the response from Apple:
"For security reasons, iPhone OS restricts an application (including its preferences and data) to a unique location in the file system. This restriction is part of the security feature known as the application's "sandbox." The sandbox is a set of fine-grained controls limiting an application's access to files, preferences, network resources, hardware, and so on."
The device's phone number is not available within your application's container. You will need to revise your application to read only within your directory container and resubmit your binary to iTunes Connect in order for your application to be reconsidered for the App Store.
This was a real disappointment since we wanted to spare the user having to enter their own phone number.
No, there's no legal and reliable way to do this.
If you find a way, it will be disabled in the future, as it has happened with every method before.
Update: capability appears to have been removed by Apple on or around iOS 4
Just to expand on an earlier answer, something like this does it for me:
NSString *num = [[NSUserDefaults standardUserDefaults] stringForKey:#"SBFormattedPhoneNumber"];
Note: This retrieves the "Phone number" that was entered during the iPhone's iTunes activation and can be null or an incorrect value. It's NOT read from the SIM card.
At least that does in 2.1. There are a couple of other interesting keys in NSUserDefaults that may also not last. (This is in my app which uses a UIWebView)
WebKitJavaScriptCanOpenWindowsAutomatically
NSInterfaceStyle
TVOutStatus
WebKitDeveloperExtrasEnabledPreferenceKey
and so on.
Not sure what, if anything, the others do.
Using Private API you can get user phone number on the following way:
extern NSString* CTSettingCopyMyPhoneNumber();
+(NSString *) phoneNumber {
NSString *phone = CTSettingCopyMyPhoneNumber();
return phone;
}
Also include CoreTelephony.framework to your project.
You cannot use iOS APIs alone to capture the phone number (even in a private app with private APIs), as all known methods of doing this have been patched and blocked as of iOS 11. Even if a new exploit is found, Apple has made clear that they will reject any apps from the app store for using private APIs to do this. See #Dylan's answer for details.
However, there is a legal way to capture the phone number without any user data entry. This is similar to what Snapchat does, but easier, as it does not require the user to type in their own phone number.
The idea is to have the app programmatically send a SMS message to a server with the app’s unique installation code. The app can then query the same server to see if it has recently received a SMS message from a device with this unique app installation code. If it has, it can read the phone number that sent it. Here’s a demo video showing the process. As you can see, it works like a charm!
This is not super easy to set up, but it be configured in a few hours at no charge on a free AWS tier with the sample code provided in the tutorial here.
As you probably all ready know if you use the following line of code, your app will be rejected by Apple
NSString *num = [[NSUserDefaults standardUserDefaults] stringForKey:#"SBFormattedPhoneNumber"];
here is a reference
http://ayeapi.blogspot.com/2009/12/sbformatphonenumber-is-lie.html
you can use the following information instead
NSString *phoneName = [[UIDevice currentDevice] name];
NSString *phoneUniqueIdentifier = [[UIDevice currentDevice] uniqueIdentifier];
and so on
#property(nonatomic,readonly,retain) NSString *name; // e.g. "My iPhone"
#property(nonatomic,readonly,retain) NSString *model; // e.g. #"iPhone", #"iPod Touch"
#property(nonatomic,readonly,retain) NSString *localizedModel; // localized version of model
#property(nonatomic,readonly,retain) NSString *systemName; // e.g. #"iPhone OS"
#property(nonatomic,readonly,retain) NSString *systemVersion; // e.g. #"2.0"
#property(nonatomic,readonly) UIDeviceOrientation orientation; // return current device orientation
#property(nonatomic,readonly,retain) NSString *uniqueIdentifier; // a string unique to each device based on various hardware info.
Hope this helps!
To get you phone number you can read a plist file. It will not work on non-jailbroken iDevices:
NSString *commcenter = #"/private/var/wireless/Library/Preferences/com.apple.commcenter.plist";
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:commcenter];
NSString *PhoneNumber = [dict valueForKey:#"PhoneNumber"];
NSLog([NSString stringWithFormat:#"Phone number: %#",PhoneNumber]);
I don't know if Apple allow this but it works on iPhones.
No official API to do it. Using private API you can use following method:
-(NSString*) getMyNumber {
NSLog(#"Open CoreTelephony");
void *lib = dlopen("/Symbols/System/Library/Framework/CoreTelephony.framework/CoreTelephony",RTLD_LAZY);
NSLog(#"Get CTSettingCopyMyPhoneNumber from CoreTelephony");
NSString* (*pCTSettingCopyMyPhoneNumber)() = dlsym(lib, "CTSettingCopyMyPhoneNumber");
NSLog(#"Get CTSettingCopyMyPhoneNumber from CoreTelephony");
if (pCTSettingCopyMyPhoneNumber == nil) {
NSLog(#"pCTSettingCopyMyPhoneNumber is nil");
return nil;
}
NSString* ownPhoneNumber = pCTSettingCopyMyPhoneNumber();
dlclose(lib);
return ownPhoneNumber;
}
It works on iOS 6 without JB and special signing.
As mentioned creker on iOS 7 with JB you need to use entitlements to make it working.
How to do it with entitlements you can find here:
iOS 7: How to get own number via private API?
AppStore will reject it, as it's reaching outside of application container.
Apps should be self-contained in their bundles, and may not read or write data outside the designated container area
Section 2.5.2 :
https://developer.apple.com/app-store/review/guidelines/#software-requirements