Unique Identifier Changing on 64 bit iOS Device - ios

Reviewed lots of questions as there are number of questions with same topic but not find with the same issue so posting.
Issue
Looking to Generate Unique Identifier for iOS Device as if user install app and with reinstall generate same identifier.
Resolved But Not Working With 64 Bit Devices
I Used this code for fetching the unique identifier for iOS device and it works fine all but when i run it on 64 bit iOS device it gives different result on every install. Please review if anyone know about the possible solution.
- (NSString *)GetUUID {
#try {
UIDevice *device = [UIDevice currentDevice];
return [[device identifierForVendor]UUIDString];
}
#catch (NSException *exception) {
return #"00000-00000-0000-00000";
}
}

The identifierForVendor will stay the same as long as app from the same developer(vendor) are installed on the device.
Thus if user uninstalls your app and there are no other app by you on the user device the identifierForVendor will be different when the user re-installs you app.
Apple has made it very clear they don't want developers track devices or installs per device. Thus you can no longer get any unique identifier from the device.
The changing of the identifierForVendor could have to do with some re-installing isseu. I've been tracking identifierForVendor and dit not see this issue.

For storing identifier betweeen reinstalls you may use this code (add SSKeychain to project)
/*
The following method determines the AppName and a uniqueidentifier and store it in the keychain
As a result when the user removes the app, downloads it again his JID and password which are derived from the
uniqueidentifier don't change.
otherwide the identifierForVendor method would return a new value on reinstall
*/
-(NSString *)getUniqueDeviceIdentifierAsString
{
NSString *appName=[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
NSString *strApplicationUUID = [SSKeychain passwordForService:appName account:#"incoding"];
if (strApplicationUUID == nil)
{
strApplicationUUID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
[SSKeychain setPassword:strApplicationUUID forService:appName account:#"incoding"];
}
return strApplicationUUID;
}

Use keychain Access to solve getting different vendor ID
Simple iPhone Keychain Access
http://useyourloaf.com/blog/2010/03/29/simple-iphone-keychain-access.html

Related

Showing wifi network doesn't work depending on building env

This question is a bit generic about building app with xcode for IOS phone
I'm a Go backend engineer but recently my company had its mobile app developed by an agency (with React-Native) and we received the source code.
Until now, the builds they made had everything working.
On my side, my company asked me to change some icons and redo a build for the app store.
In the app, we have a screen that allow you to connect to a wifi you're already connected to or list available networks:
#implementation WifiManager
//export the name of the native module as 'Wifi' since no explicit name is mentioned
RCT_EXPORT_MODULE();
//exports a method getCurrentWifiName to javascript
RCT_EXPORT_METHOD(getCurrentWifiName:(RCTResponseSenderBlock)callback){
#try{
NSString *wifiName = nil;
NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces();
for (NSString *name in interFaceNames) {
NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);
if (info[#"SSID"]) {
wifiName = info[#"SSID"];
}
}
callback(#[[NSNull null], wifiName]);
}
#catch(NSException *exception){
callback(#[exception.reason, [NSNull null]]);
}
}
#end
But those interface (wifiname, interfacenames) are always nil when I compile for release with my xcode (Version 10.1 (10B61))
So my question is, as a non-ios developper, what are the things I should look for here when building with xcode?
Is there a parameter to check / uncheck? Also, I've found on a website that CNCopySupportedInterfaces isn't supposed to work on IOS12, but depending on the build (the agency / mine) it works or not.
Anyone could explain a bit what's happening?
Many thanks!
You need to enable the Access WiFi Information capability in your project.
Navigate to the project settings, choose the "Capabilities" tab and enable the option:
I don't know React so I can't comment on the implementation but as a general rule, the simulator is not going to give you accurate feedback on anything network-related. There are ways to simulate certain network conditions to allow for rough testing of network-heavy operations but the simulator is nothing but a macOS app so it's still limited to the underlying architecture and its sandbox.
This is a long way of saying, you should be testing this on a real device.

Get UDID in iOS 8 +

I need to get the UDID of my iPhone to use in my iOS app.
Some info about my app:
My app is not for the public and will never make it to the store, so I can use any 3rd party libraries. It will only be used by some employees at work.
My device will always be plugged into a Mac, while my app is running.
The way I see it, there are only 2 ways this can be accomplished.
Use a third party library to get the UDID inside of my iOS app.
Since the iPhone will always be plugged into a Mac while my app is running, how about getting the UDID via the Mac and transferring it in some way to my app in the iPhone.
Any ideas would be appreciated. Thanks.
Edit: Question is, do you know any 3rd party libraries or a better way to get my app to automatically get the iPhone's UDID while running?
Edit 2: I know this can be done using only my phone because of this web app: http://get.udid.io/
How does this work?
If you're trying to read the UDID to automate something on the Mac, then you can use something like system_profiler SPUSBDataType to get the UDID, for my phone the entry:
Product ID: 0x12a8
Vendor ID: 0x05ac (Apple Inc.)
Version: 7.01
Serial Number: 7bed*********************************33
Speed: Up to 480 Mb/sec
Manufacturer: Apple Inc.
Location ID: 0x1d110000 / 6
Current Available (mA): 500
Current Required (mA): 500
Extra Operating Current (mA): 1600
The line Serial Number is the UDID (I've starred it out as I'm stupidly paranoid).
Note, that without the UDID you could never have got the app onto the phone in the first place.
You could run a small daemon process on the mac, reading this information and creating a bonjour service that provides the information to requestors - it's a SMOP.
It's very simple. Go to Xcode Window and select Devices or you can find it in Organizer.
http://www.raywenderlich.com/2915/ios-code-signing-under-the-hood/organizerudid
From a quick look online, it looks like you can use a private framework called libMobileGestalt.dylib.
After linking the library and importing the header, you should be able to do something like this (reference):
CFStringRef value = MGCopyAnswer(kMGUniqueDeviceID);
NSLog(#"Value: %#", value);
CFRelease(value);
On my Mac, I can find that particular dylib here:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libMobileGestalt.dylib
Use this code in ios 9
NSUUID *tempUUID = [[UIDevice currentDevice] identifierForVendor];
NSString *stringForUDID = [tempUUID UUIDString];
NSCharacterSet *notAllowedChars = [[NSCharacterSet characterSetWithCharactersInString:#"1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"] invertedSet];
NSString *resultString = [[stringForUDID componentsSeparatedByCharactersInSet:notAllowedChars] componentsJoinedByString:#""];
NSLog(#"Final string %#", resultString);
Here is the github project which seems correct for your requirement
Here is the code that works
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <liblockdown.h>
#include <stdio.h>
...
LockdownConnectionRef connection = lockdown_connect();
CFStringRef udid = (CFStringRef)lockdown_copy_value(connection, NULL, kLockdownUniqueDeviceIDKey);
CFShow(udid);
lockdown_disconnect(connection);
Use this: [[[UIDevice currentDevice] identifierForVendor] UUIDString];

Generating unique id for iphone

Hi I am developing small iphone application in which I want to generate unique id for my device. I am using following thing :
-(NSString*)uniqueIDForDevice
{
NSString* uniqueIdentifier = nil;
if( [UIDevice instancesRespondToSelector:#selector(identifierForVendor)] ) { // >=iOS 7
uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else { //<=iOS6, Use UDID of Device
CFUUIDRef uuid = CFUUIDCreate(NULL);
//uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);- for non- ARC
uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));// for ARC
CFRelease(uuid);
}
return uniqueIdentifier;
}
So i tested this code locally. Mean Every time when I uninstall and install it again it will create same unique code for me. But when I push it to app store that time for every installation on same device it is generating different code. I want to generate same code for each installation on same device. Is there any method to do this. Need some help.
I want to generate a unique identifier for device which will be same for my device even I install and uninstall application many times. I am using OIS 7.0 version.
Thank you.
The identifierForVendor changes only after a system restore, you can check some of my test here:iOS 7 access UUID value in an enterprise application (not for AppStore).
In case of iOS version lower than ios6 you can save the id in the keychain, it will persist even after app uninstall

iOS 7 access UUID value in an enterprise application (not for AppStore)

Apple since iOS7 ha deprecated and unavailable the use of the property -uniqueIdentifier. The other properties -identifierForVendor and -advertisingIdentifier have the big problem that they change the value after uninstalling and reinstalling the app.
I need that value to identify uniquely the device connected to the server.
The app will be distributed only internally using an enterprise account, so no problem for the review process.
Is there a private a method to get it?
[UPDATE WITH SOME TEST]
As David said I used identifier for vendor on iOS7.1 device here are some results from my tests.
After app installation: 28FD42B6-A993-4602-A988-69E375A1F913
After killing the app: 28FD42B6-A993-4602-A988-69E375A1F913
After deleting and reinstalling the app:
28FD42B6-A993-4602-A988-69E375A1F913
After system restore and reinstalling the app:
4948F77F-3D41-4933-B2F0-C4DCB529C7CC
After restore from backup made before system restore:
28FD42B6-A993-4602-A988-69E375A1F913
You should be able to use [UIDevice identifierForVendor] for your purpose. According to the documentation:
The value of this property is the same for apps that come from the same vendor running on the same device.
Based on that I don't think the value should change if you delete and reinstall the application. Some quick testing confirms that it is persistent through delete/install cycles.
EDIT:
It looks like identifierForVendor is only persistent through remove/install on iOS 7, so use uniqueIdentifier on iOS 6 and identifierForVendor on iOS 7 as:
#implementation UIDevice (persistentDeviceIdentifier)
-(NSString*)persistentDeviceIdentifier
{
if([self respondsToSelector:#selector(uniqueIdentifier)])
return [self performSelector:#selector(uniqueIdentifier)];
else
return [[self identifierForVendor] UUIDString];
}
#end

The advertisingIdentifier and identifierForVendor return "00000000-0000-0000-0000-000000000000"

I've implemented this methods to get advertisingIdentifier and identifierForVendor:
- (NSString *) advertisingIdentifier
{
if (!NSClassFromString(#"ASIdentifierManager")) {
return [OpenUDID value];
}
return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
- (NSString *) identifierForVendor
{
if ([[UIDevice currentDevice] respondsToSelector:#selector(identifierForVendor)]) {
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}
return #"";
}
- (BOOL)isAdvertisingTrackingEnabled
{
if (NSClassFromString(#"ASIdentifierManager") && ![[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
return NO;
}
return YES;
}
On simulator everything is working as should be and I can get the 2 strings IDs representation.
But when I run from iPhone 3GS with iOS 6.0 (10A403), these 2 methods return "00000000-0000-0000-0000-000000000000" as identifier.
Already done:
Restarted the device
Removed the app and reinstalled
Created and Ad-Hoc build, installed, removed and installed again
Run this code from another app
Tested on iPad 2 with iOS 6.0 (10A403) and everything went ok (I've got the correct identifiers)
It appears to be a bug in iOS. Seeing the same issue on devices that have been upgraded over-the-air, but devices upgraded with Xcode or iTunes work as expected without zeros.
Tried similar steps as you, and the only common theme was over-the-air (bad) versus tethered upgrade (good).
Update: Users that move directly from iOS 5.1 to 6.1 over-the-air experience a different behavior. Every time the app is closed completely and restarted, a new value is being returned by identifierForVendor. This would be expected if the app was being uninstalled and reinstalled, but that's not the case.
Apple confirmed this bug in their system in response to a Technical Support Incident request. They said that identifierForVendor and advertisingIdentifier sometimes
returning all zeros can be seen both in development builds and apps downloaded over the air from the App Store. They have no work around and can't say when the problem will be fixed.
There are some situations where API returns empty response for ID like after device restore.
Suggestion is to postpone ID retreival, so you can call sometginh like this:
-(void)retrieveID
{
if (<check fails>)
[self performSelector:#"retrieveID" withObject:nil afterDelay:1.0];
}
And fetch ID later.

Resources