im getting errors and warnings with the following code:
Warning undeclared selector uniqueIdentifier at the first if statement;
Error Property uniqueIdentifier not found on object of type UIDevice
Error Cast of C pointer type CFStringRef
// Get the users Device Model, Display Name, Unique ID, Token & Version Number
UIDevice *dev = [UIDevice currentDevice];
NSString *deviceUuid;
if ([dev respondsToSelector:#selector(uniqueIdentifier)]) // Warning #1
deviceUuid = dev.uniqueIdentifier; // Error #1
else {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id uuid = [defaults objectForKey:#"deviceUuid"];
if (uuid)
deviceUuid = (NSString *)uuid;
else {
CFStringRef cfUuid = CFUUIDCreateString(NULL, CFUUIDCreate(NULL));
deviceUuid = (NSString *)cfUuid; // Error #2
CFRelease(cfUuid);
[defaults setObject:deviceUuid forKey:#"deviceUuid"];
}
}
UIDevice uniqueIdentifier property is deprecated in iOS 5 and above
udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(#"UDID : %#", udid);
You must create a method with name uniqueIdentifier
UIDevice does not have a property called uniqueIdentifier. See this answer.
Look at this answer.
Related
I am working on one app in which I want a feature to block call. If i am passing static values to addBlockingEntryWithNextSequentialPhoneNumber it's blocking numbers but when i'm passing array in addBlockingEntryWithNextSequentialPhoneNumber it's not blocking numbers. I have logged my array in Appdelegate and it looks fine.
Appdegate Code:
NSArray *sortedArr = [lockedArr sortedArrayUsingSelector:#selector(compare:)];
[DEFAULTS setObject:sortedArr forKey:#"SortedBlockedUsers"];
NSArray<NSNumber *> *blockedPhoneNumbers = [DEFAULTS objectForKey:#"SortedBlockedUsers"];
for (NSNumber *phoneNumber in blockedPhoneNumbers) {
NSLog(#"phoneNumber == %lld", (CXCallDirectoryPhoneNumber)[phoneNumber unsignedLongLongValue]);
}
output is: phoneNumber == 918849494978 phoneNumber == 919142142124
HandlerClass code:
NSArray<NSNumber *> *blockedPhoneNumbers = [[NSUserDefaults standardUserDefaults] objectForKey:#"SortedBlockedUsers"];
//NSArray<NSNumber *> *blockedPhoneNumbers = #[ #918823514521, #919586112211 ];
for (NSNumber *phoneNumber in blockedPhoneNumbers)
{
[context addBlockingEntryWithNextSequentialPhoneNumber:(CXCallDirectoryPhoneNumber)[phoneNumber unsignedLongLongValue]];
}
Finally after debugging my extension class I found that problem is assigning value to array from NSUserDefaults. We must have to save and retrieve value using NSUserDefaults SuiteName to interact with Extension class.
I used NSUserDefaults to store an integer value. When I run the project there's a default value of 0 in it. How do I remove the 0 value? I just want it to be empty until the user put something in it.
Here is my code:
- (IBAction)save:(id)sender{
int port = [[portField text] integerValue];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:port forKey:#"port"];
[defaults synchronize];
}
- (void)viewDidLoad {
int port = [defaults integerForKey:#"port"];
NSString *portString = [NSString stringWithFormat:#"%lu",(unsigned long)port];
portField.text = portString;
[super viewDidLoad];
}
Well, this line:
int port = [defaults integerForKey:#"port"];
will always assign some value to port.
Also, this:
NSString *portString = [NSString stringWithFormat:#"%lu",(unsigned long)port];
will always produce a non-empty string. There's no value you could pass for a %lu specifier that will produce an empty string.
So, what you want to do is ask for the object that's stored in the preferences, without converting it to a integer value:
id portObject = [defaults objectForKey:#"port"];
if (portObject)
{
NSInteger port;
if ([portObject respondsToSelector:#selector(integerValue)])
port = [portObject integerValue];
else
{
// portObject is some unexpected class of object, such as an array or dictionary. Take some appropriate action. Or:
port = 0;
}
portField.text = [NSString stringWithFormat:#"%ld", (long)port];
}
else
{
// There was no value either stored or registered for the key "port"
portField.text = #"";
}
Note that for this to work, you must not have registered a default value for the "port" key using -[NSUserDefaults registerDefaults:].
As far as I know, NSUserDefaults always return default values for primitive types when they are not exists.
If the default value is a valid value you use, I suggest to put a blank object or just NSString object to determine if the associated value is valid. e.g.
NSObject *objValid = [userDefaults objectForKey:#"integerIsValid"];
if(objValid != nil) {
// User stored integer value exists.
NSInteger i = [userDefaults integerForKey:#"SomeInteger"];
} else {
// Have not saved integer value.
}
When user save the integer value, also save the associated object:
[userDefaults setObject:[[NSObject alloc]init] forKey:#"integerIsValid"];
[userDefaults setInteger:i forKey:#"SomeInteger"];
UPDATE
If your value range can transform to another value range by some rules, then you can do it another way.
All values are in range [0, 100) for example, you can store in range [1, 101) and retrieve the real value by subtracting 1.
Actually there are two errors, the first one is :
"implicit declaration of function "class_getname " is invalid in c99"
The second one is :
incompatible integer to pointer conversion initializing 'const char*' with an expression of type 'int'
my method is :
-(void) donneesrecoltees:(NSData *)donnees {
NSError *erreur;
NSNumber *lastMessage,*currentMessage;
//int i;
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString *msg;
UIAlertView *alert;
NSDictionary *json=[NSJSONSerialization JSONObjectWithData:donnees options:0 error:&erreur];
// Check if it's the right class to avoid error stack
// this is the line that is causing the error
const char* className = class_getName([json class]);
NSString *myClass=[NSString stringWithFormat:#"%s",className];
....
}
Any help on how to fix this? thank you
You need to #import <objc/runtime.h>
I want to save the string version of the NSUUID from a CBPeripheral.
I try this:
NSString *uuidString = aPeripheral.UUID;
But a warning appears:
Incompatible pointer types initializing NSString with an expression of type CFUUIDRef
- (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)aPeripheral {
NSLog(#"method didConnectPeripheral %# " , aPeripheral.UUID);
NSString *uuidString = aPeripheral.UUID;
}
The -UUID method of CBPeripheral returns a CFUUIDRef, not an NSString, and is also deprecated as of iOS 7.1. If you need to use it, either store it in a CFUUIDRef, or use CFUUIDCreateString and bridge it to an NSString.
A UUID is no string (even it is represented as a string very often.)
You can convert it into a CFStringRef with CFUUIDCreateString();
I'm adding a category to NSData as follows:
// PacketCategories.h
#interface NSData(PacketSplit)
- (NSArray *)splitTransferredPackets:(NSData **)leftover;
#end
// PacketCategories.m
#implementation NSData(PacketSplit)
- (NSArray *)splitTransferredPackets:(NSData **)leftover {
NSMutableArray *ret = [NSMutableArray array];
const unsigned char *beginning = [self bytes];
const unsigned char *offset = [self bytes];
NSInteger bytesEnd = (NSInteger)offset + [self length];
while ((NSInteger)offset < bytesEnd) {
uint64_t dataSize[1];
NSInteger dataSizeStart = offset - beginning;
NSInteger dataStart = dataSizeStart + sizeof(uint64_t);
NSRange headerRange = NSMakeRange(dataSizeStart, sizeof(uint64_t));
[self getBytes:dataSize range:headerRange];
if (dataStart + dataSize[0] + (NSInteger)offset > bytesEnd) {
NSInteger lengthOfRemainingData = [self length] - dataSizeStart;
NSRange dataRange = NSMakeRange(dataSizeStart, lengthOfRemainingData);
*leftover = [self subdataWithRange:dataRange];
return ret;
}
NSRange dataRange = NSMakeRange(dataStart, dataSize[0]);
NSData *parsedData = [self subdataWithRange:dataRange];
[ret addObject:parsedData];
offset = offset + dataSize[0] + sizeof(uint64_t);
}
return ret;
}
#end
And then trying to call that category:
#import "PacketCategories.h"
NSMutableData *data = [NSMutableData data];
// Read some data
[data appendBytes:buffer length:bytesRead];
NSArray *dataPackets = [data splitTransferredPackets:&readLeftover];
Which gets the following error:
-[NSConcreteMutableData splitTransferredPackets:]: unrecognized selector sent to instance 0x6e6f7b0
[ERROR] The application has crashed with an unhandled exception. Stack trace:
Any ideas? Does NSConcreteMutableData not inherit from NSData?
Other suggested answers (Objective-C Category Causing unrecognized selector) have suggested that the file isn't linked in, which is not possible because other categories defined in this file are used just fine.
Thanks
Ookay. I had the same problem, but with a different outcome. Briefly, the problem was in my project file. The category files showed up in the project navigator - I can load/edit, etc. But the linker did not know to link with them. The way I found this was pulling on another thread - creating a dummy concrete class in my category files to force the linker to include them. No luck. Then I tried to instantiate an instance of the dummy class in my app. Eureka - I now get a linker error! So, I simply removed and re-added the category files to the project and now all is well. Not sure how the project file got out of whack ( svn merge? ), but there it is.
Delete the Category files and add them again checking the target.
Solved for me.