How do you programmatically get the serial number of an iPhone? - iphone

I want to know the serial number of my iPhone using my application. I have writen code below.
- (NSString*)getSerialNumber
{
CFTypeRef serialNumberAsCFString;
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
if (platformExpert)
{
serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
}
IOObjectRelease(platformExpert);
NSString *serial = [[NSString alloc] initWithFormat:#"%#",serialNumberAsCFString];
NSLog(#"serail no==>%#",serialNumberAsCFString);
NSLog(#"serail no==>%#",serial);
}
Why am I still getting wrong serial number?

You should change the argument 2 of IORegistryEntryCreateCFProperty from CFSTR (kIOPlatformUUIDKey) to CFSTR (kIOPlatformSerialNumberKey). Then you will get the correct serial number(with length of 11 characters).

Are you linking the IOKit framework?
Try the
id getValue(NSString *iosearch);
function, available at
http://blogs.oreilly.com/iphone/2008/08/retrieving-device-information.html
You can also use the UIDevice class to retrieve other useful information
For instance, you can do:
NSString *id = [[UIDevice currentDevice] uniqueIdentifier];
Other useful properties are the following ones:
name
systemName
systemVersion
model
localizedModel

Ready to use category on UIDevice: UIDevice+serialNumber. Not sure this would be accepted on the App Store.

Related

Creating UUID and UDID in iOS 7

I want to create UUID, I have code below which can create UUID, how can I create UDID with multiple vendors same ID in iOS7?
+ (NSString*) stringWithNewUUID
{
CFUUIDRef uuidObj = CFUUIDCreate(nil);
NSString *newUUID = (NSString*)CFUUIDCreateString(nil, uuidObj);
CFRelease(uuidObj);
return newUUID;
}
The CFUUIDCreate function produces a version 4 UUID which is taken entirely from a pseudo-random number generator. There are no timestamps or MAC addresses embedded in this type of UUID. (That refers to the little-used version 1 flavour.) These are safe to use for nearly all applications.
This method returns random UUID in iOS 6 and above
[[UIDevice currentDevice]identifierForVendor]
I have created a vendor ID and then saved it with keychain, which I am retaining for next time using KeychainWrapper keychainStringFromMatchingIdentifier:...
The UUID that the code produces above does not have a recoverable time stamp in it. It's just a string that looks something like this: E1D87006-7CD0-4E28-9768-624DA92F75D6
I followed Sandeep Khade's answer and made following code using PDKeychainBindings. It's same as using NSUserDefaults but it keeps identifier in keychain which saves data even when application is deleted.
+ (NSString *)uniqueVendor {
PDKeychainBindings *keychain = [PDKeychainBindings sharedKeychainBindings];
NSString *uniqueIdentifier = [keychain objectForKey:kKeyVendor];
if (!uniqueIdentifier || !uniqueIdentifier.length) {
NSUUID *udid = [[UIDevice currentDevice] identifierForVendor];
uniqueIdentifier = [udid UUIDString];
[keychain setObject:uniqueIdentifier forKey:kKeyVendor];
}
return uniqueIdentifier;
}

get IMEI on iPhone with CoreTelephony?

I have tried the accepted answer of
How to get IMEI on iPhone?
but I got an empty string.
I saw somebody suggested to use CoreTelephony framework,
but I am not sure how to use it to obtain the IMEI.
Any suggestion on how to use this private API?
NOTE: this does not work anymore!
Haven't tested on any new iOS.
You have to add CoreTelephony.h to your project.
Make sure the header has
int * _CTServerConnectionCopyMobileEquipmentInfo (
struct CTResult * Status,
struct __CTServerConnection * Connection,
CFMutableDictionaryRef * Dictionary
);
Then you can try this code:
#import "CoreTelephony.h"
void getImei() {
struct CTResult it;
CFMutableDictionaryRef kCTDict;
conn = _CTServerConnectionCreate(kCFAllocatorDefault, ConnectionCallback,NULL);
_CTServerConnectionCopyMobileEquipmentInfo(&it, conn, &kCTDict);
NSLog (# "kCTDict is %#", kCTDict);
CFStringRef meid = CFDictionaryGetValue(kCTDict, CFSTR("kCTMobileEquipmentInfoMEID"));
NSLog (# "kCTMobileEquipmentInfoMEID is %#", meid);
CFStringRef mobileId = CFDictionaryGetValue(kCTDict, CFSTR("kCTMobileEquipmentInfoCurrentMobileId"));
NSLog (# "kCTMobileEquipmentInfoCurrentMobileId is %#", mobileId);
}
Here's the CoreTelephony.h
You can check my example project.
Note: I don't think the code works on the simulator and your app might get rejected.

How to reference an environment variable inside Obj-C code

I define a path variable in Xcode source tree called "MY_SRC_DIR". I would like to get the value of this environment variable and put it in a NSString in the obj-c code. For example,
-(NSString*) getSourceDir
{
return #"${MY_SRC_DIR}"; // not the right solution and this is the question
}
From http://rosettacode.org/wiki/Environment_variables#Objective-C:
[[NSProcessInfo processInfo] environment] returns an NSDictionary of the current environment.
For example:
[[[NSProcessInfo processInfo] environment] objectForKey:#"MY_SRC_DIR"]
Just expose the desired var into the Environment Variables list of your current Xcode's deployment Scheme and you'll be able to retrieve it at runtime like this:
NSString *buildConfiguration = [[NSProcessInfo processInfo] environment][#"BUILD_CONFIGURATION"];
It also applies to swift based projects.
Hope it helps!! :]
Here is another way to do it:
.xcconfig file:
FIRST_PRESIDENT = '#"Washington, George"'
GCC_PREPROCESSOR_DEFINITIONS = MACRO_FIRST_PRESIDENT=$(FIRST_PRESIDENT)
objective C code:
#ifdef FIRST_PRESIDENT
NSLog(#"FIRST_PRESIDENT is defined");
#else
NSLog(#"FIRST_PRESIDENT is NOT defined");
#endif
#ifdef MACRO_FIRST_PRESIDENT
NSLog(#"MACRO_FIRST_PRESIDENT is %#", MACRO_FIRST_PRESIDENT);
#else
NSLog(#"MACRO_FIRST_PRESIDENT is undefined, sorry!");
#endif
Console output -- I've stripped out the garbage from NSLog:
FIRST_PRESIDENT is NOT defined
MACRO_FIRST_PRESIDENT is Washington, George
The only way I've found to get a build time environment variable as a string is to put it in an dictionary element like this:
<key>Product Name</key>
<string>$PRODUCT_NAME</string>
and then retrieve it like this:
NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary];
NSString* productName = infoDict[#"Product Name"];
NSLog(#"Product Name: %#", productName);
The best answer to this question is the accepted answer on this question.
Constants in Objective-C
You'll get the most mileage, and won't need any special methods to get the value you're searching for as long as you import the file into whatever .h/.m file is going to consume said value.

custom URL scheme doesn't work! Navigon AppInteract

It is really frustrating me. I used the doc provided by Navigon itself. Unfortunately it doesn't work as expected. Navigon launches, but stops at the main menu.
All I do is this:
NSString *myTestStr = [NSString stringWithFormat:#"navigon://App|Another place|FRA|75008|PARIS|rue de Turin|17|2.324621|48.881273"];
NSString *navigonStrEsc = [myTestStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"navigonStr: %#", navigonStrEsc);
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:navigonStrEsc]];
Any ideas what is wrong with my way?
thanks a lot!
Finally I figured out the right solution. The secret ingredients that the Navigon app interchanged the latitude and longitude values.
Use this custom url scheme to pass the navigation destination coordinates (the passed coordinates have to be on the loaded map):
navigon://coordinate/YourAppName/longitude/latitude
For example: navigon://coordinate/NaviCard/19.084443/47.573305
hum it should work. Here's my code:
The only diff is that my scheme changes if FRA is installed , then navigonFRA is prefered.
NSString* scheme = #"navigonFRA";
if ((![NavigonApplication isFRInstalled]) && [NavigonApplication isWorldInstalled])
scheme = #"navigon";
NSString* urlAsString = nil;
urlAsString = [NSString stringWithFormat:#"%#://%#|%#|%#|%#|%#|%#|%#|%f|%f",
scheme,
#"myApp", // Field1/AppName:Application or Company Name (e.g. AroundMe)
thePOI.name, // Field2/NameOfPOI: Name of POI (e.g. Navigon AG Würzburg)
#"FRA", // Field3/Country: ISO 3166-1 alpha-3 code for country (http://unstats.un.org/unsd/methods/m49/m49alpha.htm) (e.g. DEU)
#"", // Field4/ZipCode: Postalcode, ZIP code of the POIs city (e.g. 97080)
thePOI.location.city, // Field5/City: Name of POIs city (e.g. Würzburg)
thePOI.location.streetAddress, // Field6/Street:POIs street name (e.g. Berliner Platz)
#"", // Field7/HouseNumber: POIs street/house number (e.g. 11)
thePOI.location.longitude, // Field8/Longitude: Longitude in WGS84 (e.g. 9.870)
thePOI.location.latitude]; // Field9/Latitude: Latitude in WGS84 (e.g. 49.938)
urlAsString = [urlAsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"Starting Navigon app with %#", urlAsString);
NSURL*url = [[NSURL alloc] initWithString:urlAsString];
[[UIApplication sharedApplication ]openURL:url];
[url release];
And this code is working. Did you check that your navigon version is >= v1.5 ?
I found the problem, the first field (AppName) is pretty important.
The following html link now works :
Some nice place
For informations : I called the navigon support yesterday, the woman who answered was helpless and terribly aggressive, I'm thinking about using TomTom now :)

How to get a Phone Number from an Address Book Contact (iphone sdk)

I am showing an addressbook view to the user and letting them click on a contact and select a phone number. If they select a phone number, I want to get the phone number as an integer and the contact's name as an NSString.
I've tried doing it with the following code:
//printf("%s\n",[[(NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty) objectAtIndex:identifier] UTF8String]);
//CFArrayRef *arrayString = [[(NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty) objectAtIndex:identifier] UTF8String];
NSArray *arrayString = [(NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty) objectAtIndex:identifier];
printf("%s\n", arrayString);
This code is inside this method:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
And I am checking if the user selected a phone number with this code:
if (propertyType == kABStringPropertyType)
{
[self wrongSelection];
}
else if (propertyType == kABIntegerPropertyType)
{
[self wrongSelection];
}
else if (propertyType == kABRealPropertyType)
{
[self wrongSelection];
}
else if (propertyType == kABMultiStringPropertyType)
{
//This is the phone number...
I am able to get the phone number to display in the console with printf, however I can't figure out how to convert it into an integer and how to also get the contacts name even though the property selected is not a person's name.
Also, what I'm doing seems very inefficient. Are there any better ways to do this?
Edit: If I can't store them as an int, a string would be fine. I just can't figure out how to go from that array to an actual string. If I cast it or save it as a UTF8String I always get some error.
To get the property efficiently (as far as reading goes), you can do something like this in your callback method:
switch( propertyType ) {
case kABMultiStringPropertyType:
// this is the phone number, do something
break;
default:
[self wrongSelection];
break;
}
I'm not sure you actually even need to parse that, though. To get the phone number from the record you could do (again, inside your callback method):
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSArray* phoneNumbers = (NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty);
CFRelease(phoneNUmberProperty);
// Do whatever you want with the phone numbers
NSLog(#"Phone numbers = %#", phoneNumbers);
[phoneNumbers release];
You can't convert the phone number into an integer. Phone numbers are strings. The default entry Apple includes for itself has the number "1-800-MYAPPLE".
Also, even if all components of a phone number are digits, there is no guarantee that phone numbers in all parts of the world are actually small enough to fit inside a 64 bit value, once you factor in area codes, country codes, internal extensions, etc. Users are free to put as much as they want in there.
Another reason not to use integers - some countries use leading zeros on phone numbers, e.g. all UK numbers start with a zero (usually written 01234 567890 or 0123 4567890)!
CFStringRef cfName = ABRecordCopyCompositeName(person);
NSString *personName = [NSString stringWithString:(NSString *)cfName];
CFRelease(cfName);
ABMultiValueRef container = ABRecordCopyValue(person, property);
CFStringRef contactData = ABMultiValueCopyValueAtIndex(container, identifier);
CFRelease(container);
NSString *contactString = [NSString stringWithString:(NSString *)contactData];
CFRelease(contactData);
contactString contains the phone number selected, and personName contains the person's name. As stated above, you can't necessarily convert the string to numbers generically, as it may contain alphabetic characters. However, you could write your own handler to convert alphabetic characters to numbers and strip out everything else to get a numeric string only, which you could then convert to a long (phone numbers get pretty long) .
I question the need to convert a phone number to a numeric value, though, since it may also contain other necessary characters like Pause. Also, a phone number represents a string of digits more than it represents one long number anyway, so the conceptual data format is more String than Int in any case.
Please be aware, that this code crashes in "stringWithString", if the Adressbook-Entry does not contain a name or a contacdata. cfName might be nil!
CFStringRef cfName = ABRecordCopyCompositeName(person);
NSString *personName = [NSString stringWithString:(NSString *)cfName];
CFRelease(cfName);
fix:
NSString *personName = nil;
if ((cfName = ABRecordCopyCompositeName(person)) != nil) {
personName = [NSString stringWithString:(NSString *)cfName];
CFRelease(cfName);
}