Generate and store a unique id in MonoTouch - ios

I am looking at transitioning an app of mine from standard iOS Objective C to C# using MonoTouch.
In my Objective C code I am generating a unique identifier and saving it to NSUserDefaults to validate and check on subsequent logins. Here is the method that I am using for that:
- (NSString *) localUuid {
NSString * ident = [[NSUserDefaults standardUserDefaults] objectForKey:UUID];
if(!ident){
CFUUIDRef uuidRef = CFUUIDCreate(NULL);
CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);
CFRelease(uuidRef);
ident = [NSString stringWithString:(__bridge_transfer NSString *)uuidStringRef];
[[NSUserDefaults standardUserDefaults] setObject:ident forKey:UUID];
[[NSUserDefaults standardUserDefaults] synchronize];
}
return ident;
}
I am having problems getting something similar to work in C# with MonoTouch though.
I haven't found a version of the CFUUID__ methods available with Mono.
Also, while there appears to be a NSUserDefaults.StandardUserDefaults.SetValueForKey method, there isn't a straightforward GetValueForKey method.
Does anyone more experienced with Monotouch know a better way to do this?

CFUUID is not bound because it's easier to use .NET System.Guid to achieve the same. E.g.
var uuid = Guid.NewGuid ();
string s = uuid.ToString (); // if a string is preferred
Also, while there appears to be a NSUserDefaults.StandardUserDefaults.SetValueForKey method, there isn't a straightforward GetValueForKey method.
There are safely type methods to do the same, e.g.:
NSUserDefaults settings = NSUserDefaults.StandardUserDefaults;
settings.SetString (s, "key");

Related

iOS Settings.bundle dictionaryForKey

Is there any option to display in iOS Settings.bundle not only standard NSUserDefaults but also for a specific key. I would like to have the serverURL setting displayed inside iOS Settings app.
static NSString * const kConfigurationKey = #"com.apple.configuration.managed";
static NSString * const kConfigurationServerURLKey = #"serverURL";
NSDictionary *serverConfig = [[NSUserDefaults standardUserDefaults] dictionaryForKey:kConfigurationKey];
NSString *serverURLString = serverConfig[kConfigurationServerURLKey];
I would like to avoid copying it from this dictionary to the main one just to have it displayed.

How to pass these parameters into an NSString nsuserdefault

I have 14 nsuserdefualt save keys and instead of adding all 14 of them I created a for loop to handle this. However I am getting an error that says too many arguments. I am probably having a brain fart and forgot something. Any tips or suggestions will be appreciated.
Edit: I am trying to read the saved data.
for (int n=0; n==14; n++ ) {
NSString *emailBody=[NSString stringWithFormat:#"Enhancers: %#",
[[NSUserDefaults standardUserDefaults]
stringForKey:#"Enhancer%i",n]];
}
You had an extra argument in your format string specifically "n" that should have been placed in a different format for stringForKey:. Something like this should clear things up:
for (int n=0; n==14; n++ ) {
NSString *stringFromDefaults = [[NSUserDefaults standardUserDefaults] stringForKey:[NSString stringWithFormat:#"%d",n]];
NSString *emailBody=[NSString stringWithFormat:#"Enhancers: %#",stringFromDefaults];
}

Array of CFUUIDs?

Here's my code:
- (void)peripheralManager:(CBPeripheralManager *)peripheralManager central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic
{
[self.centralManager retrievePeripherals:#[central.UUID]];
}
I get an error:
Collection element of type 'CFUUIDRef' (aka 'const struct __CFUUID *') is not an Objective-C object
What do I do?
The problem:
The compiler only knows about types, not about runtime behavior. It doesn't know that - most probably - CFUUIDRef can be used just like any normal Objective-C object (although it doesn't officially have a toll-free bridged Foundation class counterpart). It only sees that const struct __CFUUID is not an Objective-C class, and it bails out.
The solution:
I. I presume this will work - just tried it and it indeed works, CFUUID even has a nice description when printed using NSLog(). However, it is not documented. Just cast it to id, like this:
#[(__bridge id)central.UUID]
II. Yes, you can convert it to a string, but that won't make the compiler error go away either - you do need that typecast, because the compiler quirks about the incompatible types:
CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault,#[central.UUID]);
NSString *uuidNSString = (__bridge NSString *)uuidString;
Now this is guaranteed to work.
My recommendation would be to convert it to an NSString and add that to the array.
+ (NSString *)convertUUID:(CFUUIDRef)theUUID
{
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return (__bridge_transfer NSString *)string;
}
Try converting it to a Objective-C Object:
CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, yourUUID);
NSString *uuidNSString = (__bridge NSString *)uuidString;
And if you need it back:
CFUUIDRef uuid = CFUUIDCreateFromString(kCFAllocatorDefault, uuidString);

UUID v1 Objective-C implementation

I want to implement UUID v1 in my iOS App.
I know that it is composed of Mac Address and timestamp as described in
http://en.wikipedia.org/wiki/Universally_unique_identifier#Version_1_.28MAC_address.29
Is there any objective-c implementation for this V1, based on CFUUID functions ?
I already have the mac address and the timestamp.
The UUID v1 description at Wikipedia : "The original (version 1) generation scheme for UUIDs was to concatenate the UUID version with the MAC address of the computer that is generating the UUID, and with the number of 100-nanosecond intervals since the adoption of the Gregorian calendar in the West"
It is also specified at http://www.ietf.org/rfc/rfc4122.txt , but it seems that it will need time to implement it.
I have found this link : http://www.famkruithof.net/guid-uuid-timebased.html who have a simple explanation for the steps to create a v1 UUID. Is there any existing implementation, before I implement it by my self?
I thinks it is common behavior to use framework functions. And that is use CFUUID. For example:
+(NSString*)get {
NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:#"DeviceID"];
if (!deviceID) {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
deviceID = (NSString*)string;
[[NSUserDefaults standardUserDefaults] setValue:deviceID forKey:#"DeviceID"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
return deviceID;
}
Please try this one. It may be helpful to you
+(NSString*) Create_UDID
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
NSString* strString = [NSString stringWithFormat:#"%#", string];
NSString *strValue = [strString stringByReplacingOccurrencesOfString:#"-"withString:#""];
if (strValue == nil) {
strValue = #"";
}
return strValue;
}

Sharing a NSString between two views

I need to share a string between two views in my application. When the user ends the game, the score is converted into a string. I then need to transfer that string into a different view controller where I display the score. I have a label set up and all but the view is not recognizing the string even though I am importing the header file from which the string is created. Any help would be great, thank.
This is my view controller where the string is created
NSString *scoreString = [NSString stringWithFormat:#"%d", score];
And this is where I try to display the string in a different view controller
- (void)viewDidLoad {
self.scoreString = score.text;
[super viewDidLoad];
}
For scores and similar data, you may want to use NSUserDefaults. These can be accessed at any time from any UIViewController. For example, you can implement methods similar to these to save and retrieve the data:
-(void)saveToUserDefaults:(NSString*)myString
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:myString forKey:#"Score"];
[standardUserDefaults synchronize];
}
}
-(NSString*)retrieveFromUserDefaults
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *val = nil;
if (standardUserDefaults)
val = [standardUserDefaults objectForKey:#"Score"];
return val;
}
NSUserDefaults also handles ints, BOOLs, NSArrays, etc. Check out the documentation or google around for examples.
You could use delegates or NSUserDefaults
Been asked similiar questions before:
Passing variables to different view controllers
How do I pass variables between view controllers?
EDIT
[[NSUserDefaults standardUserDefaults] setObject:#"STRING HERE" forKey:#"MyKey"];
and retrieve
[[NSUserDefaults standardUserDefaults] objectForKey:#"MyKey"];

Resources