.h
#import <Foundation/Foundation.h> #import <Security/Security.h> /**使用**/ //-(void) setKeyChainValue //{ // KeychainItemWrapper *keyChainItem=[[KeychainItemWrapper alloc]initWithIdentifier:@"TestUUID" accessGroup:@"XXXXXX.h.HelloWorld"]; // NSString *strUUID = [keyChainItem objectForKey:(id)kSecValueData]; // if (strUUID==nil||[strUUID isEqualToString:@""]) // { // [keyChainItem setObject:[self gen_uuid] forKey:(id)kSecValueData]; // } // [keyChainItem release]; // //} // //-(NSString *) gen_uuid //{ // CFUUIDRef uuid_ref=CFUUIDCreate(nil); // CFStringRef uuid_string_ref=CFUUIDCreateString(nil, uuid_ref); // CFRelease(uuid_ref); // NSString *uuid=[NSString stringWithString:uuid_string_ref]; // CFRelease(uuid_string_ref); // return uuid; //} //Define an Objective-C wrapper class to hold Keychain Services code. @interface KeychainWrapper : NSObject { NSMutableDictionary *keychainData; NSMutableDictionary *genericPasswordQuery; } @property (nonatomic, strong) NSMutableDictionary *keychainData; @property (nonatomic, strong) NSMutableDictionary *genericPasswordQuery; - (void)mySetObject:(id)inObject forKey:(id)key; - (id)myObjectForKey:(id)key; - (void)resetKeychainItem; +(instancetype) shareManager; /**获取唯一的UUID**/ -(NSString *) KeyChainValue; @end
.m
#import "KeychainWrapper.h" /* ********************************************************************** */ //Unique string used to identify the keychain item: static const UInt8 kKeychainItemIdentifier[] = "com.apple.dts.KeychainUI "; @interface KeychainWrapper (PrivateMethods) //The following two methods translate dictionaries between the format used by // the view controller (NSString *) and the Keychain Services API: - (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert; - (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert; // Method used to write data to the keychain: - (void)writeToKeychain; @end @implementation KeychainWrapper //Synthesize the getter and setter: @synthesize keychainData, genericPasswordQuery; static KeychainWrapper *manager = nil; +(instancetype) shareManager { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ manager = [[KeychainWrapper alloc]init]; }); return manager; } /**获取唯一的UUID**/ -(NSString *) KeyChainValue { NSString *strUUID = [self myObjectForKey:(id)kSecValueData]; if (strUUID==nil||[strUUID isEqualToString:@""]) { [self mySetObject:[self uuid] forKey:(id)kSecValueData]; strUUID = [self uuid]; // 首次获取为空,需要赋值 } return strUUID; } -(NSString*) uuid { CFUUIDRef puuid = CFUUIDCreate( nil ); CFStringRef uuidString = CFUUIDCreateString( nil, puuid ); NSString * result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString)); CFRelease(puuid); CFRelease(uuidString); return result; } - (id)init { if ((self = [super init])) { OSStatus keychainErr = noErr; // Set up the keychain search dictionary: genericPasswordQuery = [[NSMutableDictionary alloc] init]; // This keychain item is a generic password. [genericPasswordQuery setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; // The kSecAttrGeneric attribute is used to store a unique string that is used // to easily identify and find this keychain item. The string is first // converted to an NSData object: NSData *keychainItemID = [NSData dataWithBytes:kKeychainItemIdentifier length:strlen((const char *)kKeychainItemIdentifier)]; [genericPasswordQuery setObject:keychainItemID forKey:(__bridge id)kSecAttrGeneric]; // Return the attributes of the first match only: [genericPasswordQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; // Return the attributes of the keychain item (the password is // acquired in the secItemFormatToDictionary: method): [genericPasswordQuery setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; //Initialize the dictionary used to hold return data from the keychain: CFMutableDictionaryRef outDictionary = nil; // If the keychain item exists, return the attributes of the item: keychainErr = SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&outDictionary); if (keychainErr == noErr) { // Convert the data dictionary into the format used by the view controller: self.keychainData = [self secItemFormatToDictionary:(__bridge_transfer NSMutableDictionary *)outDictionary]; } else if (keychainErr == errSecItemNotFound) { // Put default values into the keychain if no matching // keychain item is found: [self resetKeychainItem]; if (outDictionary) CFRelease(outDictionary); } else { // Any other error is unexpected. NSAssert(NO, @"Serious error. "); if (outDictionary) CFRelease(outDictionary); } } return self; } // Implement the mySetObject:forKey method, which writes attributes to the keychain: - (void)mySetObject:(id)inObject forKey:(id)key { if (inObject == nil) return; id currentObject = [keychainData objectForKey:key]; if (![currentObject isEqual:inObject]) { [keychainData setObject:inObject forKey:key]; [self writeToKeychain]; } } // Implement the myObjectForKey: method, which reads an attribute value from a dictionary: - (id)myObjectForKey:(id)key { return [keychainData objectForKey:key]; } // Reset the values in the keychain item, or create a new item if it // doesn't already exist: - (void)resetKeychainItem { if (!keychainData) //Allocate the keychainData dictionary if it doesn't exist yet. { self.keychainData = [[NSMutableDictionary alloc] init]; } else if (keychainData) { // Format the data in the keychainData dictionary into the format needed for a query // and put it into tmpDictionary: NSMutableDictionary *tmpDictionary = [self dictionaryToSecItemFormat:keychainData]; // Delete the keychain item in preparation for resetting the values: OSStatus errorcode = SecItemDelete((__bridge CFDictionaryRef)tmpDictionary); NSAssert(errorcode == noErr, @"Problem deleting current keychain item." ); } // Default generic data for Keychain Item: // [keychainData setObject:@"Item label" forKey:(__bridge id)kSecAttrLabel]; // [keychainData setObject:@"Item description" forKey:(__bridge id)kSecAttrDescription]; // [keychainData setObject:@"Account" forKey:(__bridge id)kSecAttrAccount]; // [keychainData setObject:@"Service" forKey:(__bridge id)kSecAttrService]; // [keychainData setObject:@"Your comment here." forKey:(__bridge id)kSecAttrComment]; // [keychainData setObject:@"password" forKey:(__bridge id)kSecValueData]; } // Implement the dictionaryToSecItemFormat: method, which takes the attributes that // you want to add to the keychain item and sets up a dictionary in the format // needed by Keychain Services: - (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert { // This method must be called with a properly populated dictionary // containing all the right key/value pairs for a keychain item search. // Create the return dictionary: NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert]; // Add the keychain item class and the generic attribute: NSData *keychainItemID = [NSData dataWithBytes:kKeychainItemIdentifier length:strlen((const char *)kKeychainItemIdentifier)]; [returnDictionary setObject:keychainItemID forKey:(__bridge id)kSecAttrGeneric]; [returnDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; // Convert the password NSString to NSData to fit the API paradigm: NSString *passwordString = [dictionaryToConvert objectForKey:(__bridge id)kSecValueData]; [returnDictionary setObject:[passwordString dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge id)kSecValueData]; return returnDictionary; } // Implement the secItemFormatToDictionary: method, which takes the attribute dictionary // obtained from the keychain item, acquires the password from the keychain, and // adds it to the attribute dictionary: - (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert { // This method must be called with a properly populated dictionary // containing all the right key/value pairs for the keychain item. // Create a return dictionary populated with the attributes: NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert]; // To acquire the password data from the keychain item, // first add the search key and class attribute required to obtain the password: [returnDictionary setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; [returnDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; // Then call Keychain Services to get the password: CFDataRef passwordData = NULL; OSStatus keychainError = noErr; // keychainError = SecItemCopyMatching((__bridge CFDictionaryRef)returnDictionary, (CFTypeRef *)&passwordData); if (keychainError == noErr) { // Remove the kSecReturnData key; we don't need it anymore: [returnDictionary removeObjectForKey:(__bridge id)kSecReturnData]; // Convert the password to an NSString and add it to the return dictionary: NSString *password = [[NSString alloc] initWithBytes:[(__bridge_transfer NSData *)passwordData bytes] length:[(__bridge NSData *)passwordData length] encoding:NSUTF8StringEncoding]; [returnDictionary setObject:password forKey:(__bridge id)kSecValueData]; } // Don't do anything if nothing is found. else if (keychainError == errSecItemNotFound) { NSAssert(NO, @"Nothing was found in the keychain. "); if (passwordData) CFRelease(passwordData); } // Any other error is unexpected. else { NSAssert(NO, @"Serious error. "); if (passwordData) CFRelease(passwordData); } return returnDictionary; } // Implement the writeToKeychain method, which is called by the mySetObject routine, // which in turn is called by the UI when there is new data for the keychain. This // method modifies an existing keychain item, or--if the item does not already // exist--creates a new keychain item with the new attribute value plus // default values for the other attributes. - (void)writeToKeychain { CFDictionaryRef attributes = nil; NSMutableDictionary *updateItem = nil; // If the keychain item already exists, modify it: if (SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr) { // First, get the attributes returned from the keychain and add them to the // dictionary that controls the update: updateItem = [NSMutableDictionary dictionaryWithDictionary:(__bridge_transfer NSDictionary *)attributes]; // Second, get the class value from the generic password query dictionary and // add it to the updateItem dictionary: [updateItem setObject:[genericPasswordQuery objectForKey:(__bridge id)kSecClass] forKey:(__bridge id)kSecClass]; // Finally, set up the dictionary that contains new values for the attributes: NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainData]; //Remove the class--it's not a keychain attribute: [tempCheck removeObjectForKey:(__bridge id)kSecClass]; // You can update only a single keychain item at a time. OSStatus errorcode = SecItemUpdate( (__bridge CFDictionaryRef)updateItem, (__bridge CFDictionaryRef)tempCheck); NSAssert(errorcode == noErr, @"Couldn't update the Keychain Item." ); } else { // No previous item found; add the new item. // The new value was added to the keychainData dictionary in the mySetObject routine, // and the other values were added to the keychainData dictionary previously. // No pointer to the newly-added items is needed, so pass NULL for the second parameter: OSStatus errorcode = SecItemAdd( (__bridge CFDictionaryRef)[self dictionaryToSecItemFormat:keychainData], NULL); NSAssert(errorcode == noErr, @"Couldn't add the Keychain Item." ); if (attributes) CFRelease(attributes); } } @end
获取设备的IP地址
#import "getIPhoneIP.h" #import <ifaddrs.h> #import <arpa/inet.h> @implementation getIPhoneIP //create by huangys +(NSString *)getIPAddress { NSString *address = @"error"; struct ifaddrs *interfaces = NULL; struct ifaddrs *temp_addr = NULL; int success = 0; // retrieve the current interfaces - returns 0 on success success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces temp_addr = interfaces; while(temp_addr != NULL) { if(temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; } } temp_addr = temp_addr->ifa_next; } } // Free memory freeifaddrs(interfaces); return address; } @end