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.
The following is returning an error because evidently I cannot compare an NSInteger or int to nil. Can anyone suggest syntax to do this
NSInteger *lastID = [[NSUserDefaults standardUserDefaults] integerForKey:#"lastID"]==nil ? #1 : [[NSUserDefaults standardUserDefaults] integerForKey:#"lastID"];
NSInteger lastID = [[NSUserDefaults standardUserDefaults] integerForKey:#"lastID"] == 0 ? 1 : [[NSUserDefaults standardUserDefaults] integerForKey:#"lastID"];
NSInteger is a primitive type. nil is for objects. 0 check, checks is your userDefaults' integer value assigned a value. If it didn't assigned, it returns 0.
NSInteger is a primitive type, not an object. I'm quite sure that an NSInteger* is not what you want, but an NSInteger. integerForKey returns an NSInteger, not an NSInteger*.
NSInteger is a primitive, not an NSObject, so any hypothetical comparison to nil would effectively be comparing to numeric zero.
Since you are using the ternary operator to assign lastID to the boxed NSNumber #1 if the result would be nil, then it seems what you want to do is store an NSNumber in the defaults, use objectForKey: to retrieve it, and use integerValue on the retrieved NSNumber to get the primitive value.
If you do indeed want to store primitives, that's fine, but you'll need to change your logic to not expect nil, which is only pertinent to sublcasses of NSObject, basically.
UPDATE: an example app.
#import <Foundation/Foundation.h>
enum {
MyIdTypeUnrecognized = 0,
MyIdTypeInvalid = 1
} myIdType;
int main(int argc, char *argv[]) {
#autoreleasepool {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *key = #"lastID";
NSInteger lastID = -100;
[defaults removeObjectForKey:key];
NSLog(#"Case 1: should find 0, and set lastID to 1.");
lastID = [defaults integerForKey:key];
lastID = (lastID == MyIdTypeUnrecognized) ? MyIdTypeInvalid : lastID;
NSLog(#"--- lastID:%ld", lastID);
NSLog(#"Case 2: Set lastID to 2, then try to fetch.");
lastID = -100;
[defaults setInteger:2 forKey:key];
[defaults synchronize];
lastID = [defaults integerForKey:key];
lastID = (lastID == MyIdTypeUnrecognized) ? MyIdTypeInvalid : lastID;
NSLog(#"--- lastID:%ld", lastID);
}
}
//2015-09-04 10:04:38.075 nsnotfound[66983:5231434] Case 1: should find 0, and set lastID to 1.
//2015-09-04 10:04:38.076 nsnotfound[66983:5231434] --- lastID:1
//2015-09-04 10:04:38.076 nsnotfound[66983:5231434] Case 2: Set lastID to 2, then try to fetch.
//2015-09-04 10:04:38.076 nsnotfound[66983:5231434] --- lastID:2
I suggested using NSNumber earlier, as your question used a boxed NSNumber -- #1. #1 is simply shorthand for [NSNumber numberWithInteger:1]. If you don't want to use objects, you can definitely use primitives.
The example above uses both zero and one as sentinel values for your "unfound" and "invalid" IDs. All other IDs should be usable by your app logic. I hope this helps.
You can retrieve this number to NSNumber which is an object and that way you can check if it is nil or not.
NSInteger is basically a typecast of Int in 32 bit or long in 64 bit, as you compare int in similar way you can compare NSInteger.It will never be nil.
NSInteger isn't an object, its a primitive type stored as a NSNumber inside NSUserDefaults. Checking for existence of primitive types is a bit tricky, as its non-existence is equivalent to nil or 0. The cleanest way to get its value and get a default value if it doesn't exist is probably this way:
NSNumber *lastID = [[NSUserDefaults standardUserDefaults] objectForKey:#"lastID"] ?: #1;
This would return you lastID if it exists, otherwise you get a NSNumber with a value of 1.
I have this bit of code where I put objects into a NSMutableDictionary:
SingletonDictionary *sd = [SingletonDictionary sharedDictionary];
UITextField *tf = (UITextField *)sender;
int tagValue = tf.tag; // get the tag value
[sd.dictionaryOfUserIndexes setObject:tf.text forKey:[NSString stringWithFormat:#"%d", tagValue]]; // value found in textField id'd by tag
UPDATED: This is the code where I'm trying to retrieve the contents of the dictionary:
SingletonDictionary *sd = [SingletonDictionary sharedDictionary]; // initialize
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // here too...
sd.dictionaryOfUserIndexes = [defaults objectForKey:#"importFileIDs"]; // move from standardUserDefaults to dictionary singleton
NSLog(#"\n\nsd.dictionaryOfUserIndexes: %#", sd.dictionaryOfUserIndexes);
[sd.dictionaryOfUserIndexes[intTagValue]]]; // move contents of textField from dictionary
textField.text = [sd.dictionaryOfUserIndexes objectForKey: tagValue];
This is the contents of sd.dictionaryOfUserIndexes:
sd.dictionaryOfUserIndexes: {
0 = 2;
1 = 5;
2 = 8;
4 = 7;
}
The first column is the tag of the UITextField; the 2nd column is the data in that textField
The contents of the dictionary are valid; I got rid of the build errors, but when I run this, there is nothing in the textField.
I have looked and looked at this, and just hope I didn't do something stupid. Can someone please tell me what's wrong?
I figured it out...
textField.text = [sd.dictionaryOfUserIndexes objectForKey: [tagValue stringValue]];
Thanks everybody for your time; I appreciate it.
I'm trying to compare a value to one stored in a NSString, but I get the following error:
Implicit conversion of int to 'NSArray *' is disallowed with ARC
Here is my code:
NSString *tmplabel = [tmpC description];
temp.text = [NSString stringWithFormat: #"%.f", [tmplabel doubleValue]];
if (tmpC >= 10) {
// perform action
}
else {
// perform action
}
How can I do this comparison? I just want to see if the value stored is bigger than or equal to 10.
Thanks for your time :)
I have the following code;
int days = [[SettingsUtils daysToRetainHistory] intValue];
[retainHistory setText:[NSString stringWithFormat:#"Days to retain History: %d", days]];
[daysToRetainHistory setValue:days animated:NO];
where [SettingsUtils daysToRetainHistory] is as follows;
+ (int) daysToRetainHistory {
return (int)[[NSUserDefaults standardUserDefaults] objectForKey:#"CaseBaseDaysToRetainHistory"];
}
I get the compiler warning Invalid receiver type 'int' because I call intValue on an int but unless I do this I can't seem to get the integer value out and always end up with the memory address i.e. 98765432 instead of 9 which ruins the UILabel display [retainHistory] and the UISlider [daysToRetainHistory] value.
How do I avoid the compiler warning and still get my integer value in the label and the necessary float value for setting the UISlider value?
It's because you are casting a memory address to an int that int value isn't working. Instead just use the method you want from NSUserDefaults:
+ (NSInteger)daysToRetainHistory
{
return [[NSUserDefaults standardUserDefaults] integerForKey:#"CaseBaseDaysToRetainHistory"];
}
then just use it directly:
NSInteger days = [SettingsUtils daysToRetainHistory];
You should also store your days with the same method:
[[NSUserDefaults standardUserDefaults] setInteger:days forKey:#"CaseBaseDaysToRetainHistory"];
Although if you set the NSNumber object and it actually does contain an integer, that will work fine too.