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;
}
Related
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.
I want to get latest tweets posted after a particular tweet/time. I'm using MGTwitterEngine for iOS.
I fetch the id of the last tweet posted like this (variable statusId)
- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier`
{
NSMutableDictionary *statusDict = [NSMutableDictionary dictionaryWithDictionary:[[Shared sharedInstance].tweets objectAtIndex:i]];
NSString *idstr = [statusDict valueForKey:#"id"];
statusId = unsigned long version of idstr using NSNumberFormatter;
}
I store this statusId as a global variable and again when I call
-(void) getTweets
{
[twitterEngine getUserTimelineFor:title sinceID:statusId startingAtPage:0 count:20];
}
it returns the old tweets and not new ones posted after the last tweet.
Also when I do an NSLog of the statusID stored and the string value of the ID, they are printed different (even though according to docs, both should be unsigned long)
Can someone please let me know how to get tweets posted after a specific tweet/time?
Thanks.
Is there no solution t this problem. I posted the problem yesterday and since then no reply has come.
In order to get the latest tweets statusID has to be a unsigned long long.
I want to register the default values in NSUserDefaults so that the user settings do not return null values for values not explicitly set by the user, but rather return the default values specified in settings bundle. I read here:
How to register user defaults using NSUserDefaults without overwriting existing values?
that the following should be executed in applicationDidFinishLaunching:
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Defaults" ofType:#"plist"]]];
How can this be done in MonoTouch?
I solved this by using the method detailed in this question:
Can you make the settings in Settings.bundle default even if you don't open the Settings App
I basically translated the function registerDefaultsFromSettingsBundle listed there into MonoTouch. This is a very useful function because it calls registerDefaults for the default values listed in the settings bundle. This ensures that if the user has not entered any values, that the defined default values will be returned rather than null values. This can be called from FinishedLaunching of the AppDelegate.
Here is the MonoTouch version of this function:
public static void RegisterDefaultsFromSettingsBundle()
{
string settingsBundle = NSBundle.MainBundle.PathForResource("Settings", #"bundle");
if(settingsBundle == null) {
System.Console.WriteLine(#"Could not find Settings.bundle");
return;
}
NSString keyString = new NSString(#"Key");
NSString defaultString = new NSString(#"DefaultValue");
NSDictionary settings = NSDictionary.FromFile(Path.Combine(settingsBundle,#"Root.plist"));
NSArray preferences = (NSArray) settings.ValueForKey(new NSString(#"PreferenceSpecifiers"));
NSMutableDictionary defaultsToRegister = new NSMutableDictionary();
for (uint i=0; i<preferences.Count; i++) {
NSDictionary prefSpecification = new NSDictionary(preferences.ValueAt(i));
NSString key = (NSString) prefSpecification.ValueForKey(keyString);
if(key != null) {
NSObject def = prefSpecification.ValueForKey(defaultString);
if (def != null) {
defaultsToRegister.SetValueForKey(def, key);
}
}
}
NSUserDefaults.StandardUserDefaults.RegisterDefaults(defaultsToRegister);
}
I hope other MonoTouch developers find this useful.
UPDATE:
With the latest version of Xamarin.iOS this code will throw an exception on this line:
NSDictionary prefSpecification = new NSDictionary(preferences.ValueAt(i));
Note that this exception does not occur because of iOS 8 but because Xamarin has decided to make the constructor that the code is depending on private, so the required constructor is not available to be used. I resolved this by subclassing NSDictionary like this:
public class CustomNSDictionary: NSDictionary
{
public CustomNSDictionary (IntPtr ptr): base(ptr) {}
}
Then you can replace the problematic line with the following:
CustomNSDictionary prefSpecification = new CustomNSDictionary(preferences.ValueAt(i));
You could try something along the lines of:
NSUserDefaults.StandardUserDefaults.RegisterDefaults(NSDictionary.FromFile("Defaults.plist"));
(assuming you've created a Defaults.plist file with all your default values in! (and it's in the root of your bundle!))
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.
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);
}