ios assigning value to a string from an array - ios

So I have a basic array:
NSMutableArray *answerButtonsArrayWithURL = [NSMutableArray arrayWithObjects:self.playView.coverURL1, self.playView.coverURL2, self.playView.coverURL3, self.playView.coverURL4, nil];
The objects inside are strings. I want to access a random object from that array
int rndValueForURLS = arc4random() % 3;
and assigning it a value. I've tried manny different approaches but my recent one is
[[answerButtonsArrayWithURL objectAtIndex:rndValueForURLS] stringByAppendingString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
Any help will be much appreciated. Thanks

You need to assign it. You're already building the new value like that:
NSString *oldValue = answerButtonsArrayWithURL[rndValueForURLS];
NSString *newValue = [oldValue stringByAppendingString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
The part you're missing :
answerButtonsArrayWithURL[rndValueForURLS] = newValue;
Above would be the way to replace the immutable string with another. If the strings are mutable, that is, they were created as NSMutableString, you could do:
NSMutableString *value = answerButtonsArrayWithURL[rndValueForURLS];
[value appendString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
Note:
Everywhere I replace the notation :
[answerButtonsArrayWithURL objectAtIndex:rndValueForURLS];
with the new equivalent and IMO more readable:
answerButtonsArrayWithURL[rndValueForURLS];

Related

Objective C: A cleaner way to check if a string isn't empty before creating and assigning a string to a dictionary key?

I am creating an NSMutableDictionary and assigning an NSString (test and test1) to a parameter key.
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
if (test.length) {
dictionary[#"test"] = test;
}
if (test1.length) {
dictionary[#"test1"] = test1;
}
This method does work. However, I am going to eventually have more strings and don't want a bunch of if statements. I don't want the dictionary keys to exist if the string is empty or nil.
Not sure if there is a way around this.
I thought about creating a separate function that accepts an array of key string and array of string values and use a for loop to see if string value is empty. Then, return a dictionary once the for loop ends. However, you can't insert nil into an NSArray
Something like this
- (void)updateDic:(NSMutableDictionary *)dic withString:(NSString *)str {
if (!str || [str isEqualToString:#""]) {
return;
}
dic[str] = str;
}
And then just iterate over all strings and use that method.
What I'd do is create a NSMutableDictionary category, something like this:
NSMutableDictionary+CustomMethods.m:
- (void)setStringIfNotNil:(NSString *)string forKey:(id <NSCopying>)key {
if (!string || !string.length) { return; }
self[key] = string;
}
Then you can use it like this:
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setStringIfNotNil:test forKey:#"test"]
[dictionary setStringIfNotNil:test1 forKey:#"test1"]
There are three ways according to me..
The first one use the category in which you have to write if condition only single time and you can use it in any class of your project.
Second one by making a separate method to do that task(to check string nil or not and adding into the dictionary).
And the third one , just add all in an array and and perform the action in a loop.
The syntax:
dictionary[#"test"] = test
will remove the value from the dictionary if test is nil (it's a difference between the normal -setObject:forKey: method and the -setObject:forKeyedSubcript: which that syntax invokes). However, that will not work for empty strings.
As mentioned in another answer, you could make an NSDictionary category method to check, then call that method instead.
You could also just use the regular dictionary[key] = value syntax, then when you are done, do:
[dictionary removeObjectsForKeys:[dictionary allKeysForObject:#""]];
If it's possible to have the keys repeated, and you don't want an empty string overriding an earlier valid valid, you would have to check each time -- either by the category method, or using a local macro or inline function or local method.
static inline void SetValidVal(NSMutableDictionary *dictionary, NSString *key, NSString *val) {
if (val.length) { dictionary[key] = val; }
}
or
#define MY_SET_VALID_VAL(dictionary, key, val) if ((val).length) dictionary[key] = (val)
If the key names need to be the same as the name of the local variable, you can play other games with macros (this also assumes the local variable name "dictionary":
#define MY_UPDATE_VAL(val) if (val.length) dictionary[##val] = (val)
Then MY_UPDATE_VAL(test1); would expand to:
if (test1.length) dictionary[#"test1"] = test1;
That's a bit magic though and probably not recommended.

objc How do I get the string object from this Json array?

This is part of an incoming array:
variantArray: (
(
{
CardinalDirection = "North-West";
DirectionVariantId = "DcCi_1445_171_0_0";
Distance = "2.516606318971459";
RouteName = "Woodsy";
Shape = {
Points = (
{
I want to get the value of DirectionVariantId
I would normally loop and use
NSMutableArray *myString = [variantArray[i] valueForKey:#"DirectionVariantId"];
This isn't working and results in an exception when I try to examine the last character in the string:
NSString *lastChar = [myString substringFromIndex:[myString length] - 1];
This is a new data set for me and I'm missing something..
Thanks for any tips.
Json contain two curly bracket means nested array.
Try:
NSString *myString=[[[variantArray objectAtIndex:0] objectAtIndex:0] objectForKey:#"DirectionVariantId"];
I think you're looking for [variantArray[i] objectForKey:#"DirectionVariantId"];
You'd need to convert the object within your incoming array (variantArray[i]) to a NSDictionary but it might already be judging by your original output.

How do you put a variable in the array brackets in Xcode 5?

When I do an operation like this:
self.slider.value = randomArray[0][0];
I would like to be able to do this:
self.slider.value = randomArray[randomVariable][0];
Basically, how do you put that "randomVariable" in the brackets? When I try to do this on Xcode, I get:
Code: self.detail1.text = detailsForNotesUse[x][0];
Error:Expected Method to read dictionary element not found in object
of type 'NSArray *'
The variable I put in the brackets is NSString, the array is NSArray, and detail1 is a text field.
Declarations:
NSString *x = 0;
NSArray *detailsForNotesUse;
You've defined x as an NSString. You should define your index variable like this:
NSUInteger x = 0;
I'm just reposting the answer I gave in my comment below the question:
x needs to be an int if you're using it as an index. ex. int x = 0;
But I'm also writing to note that many of the answers are misleading. You can in fact access a nested array in this way, i.e. randomArray[x][y];, because if randomArray[x] returns an array (as is syntactically valid in obj-c), the items of that array can then be similarly accessed by appending [y] (though you may have to cast randomArray[x] to an NSArray to prevent a warning).

Accessing NSDictionary retrieves an object instead of NSString

I have an NSDictionary that I fill with JSON. It all looks great, and it is partially working for me. I am setting a property of my class that is of type NSString equal to a value for a certain key, which oddly enough sets my property equal to an object with the object being the string value I need.
The dictionary (printed description):
miscInfo:
<__NSArrayI 0x7494ab0>(
{
Abbreviation = DR;
DateInactive = "";
Description = Drowsiness;
ForQueue = 2430;
IsAdditive = 0;
IsReserved = 1;
MiscCodeTypeStr = AVR;
PluralDescription = "";
ReservedDescription = Drowsiness;
}
I am setting it on my property like so:
self.ReactionName = [miscInfo valueForKeyPath:#"Description"];
Which produces:
I've tried casting it as NSString such as:
self.ReactionName = (NSString*)[allergenAdverseReaction valueForKeyPath:#"Description"];
but nothing gives. What am I doing wrong?
miscInfo is an array containing a dictionary, so
self.ReactionName = [[miscInfo objectAtIndex:0] objectForKey:#"Description"];
would give the result that you expect. Or, using the modern array and dictionary
subscripting syntax:
self.ReactionName = miscInfo[0][#"Description"];
Remark: In your code
self.ReactionName = [miscInfo valueForKeyPath:#"Description"];
valueForKeyPath is applied to each element of the array, and an array with all
the values is returned. That is what you see in the Xcode debugger window.
This "feature" can be very useful, but in general (as Hot Licks commented above)
objectForKey is the right method to get a value from a dictionary. And
self.ReactionName = [miscInfo objectForKey:#"Description"];
throws a descriptive runtime exception if miscInfo is not a dictionary as expected.
It looks to me like miscInfo is an array of dictionaries. In that case valueForKey will return an array. See if the code below works. If it does, then it is an array of dictionaries.
self.ReactionName = [[allergenAdverseReaction valueForKeyPath:#"Description"]lastObject];

adding Char or NSString into Objective C enum

I have created an enum in my header file that looks like this
typedef enum {stTMD = 1, stT2MD = 2, stDCMD = 'D', stMBMD = 'M'} stTypes;
First off I am not even sure if thats the correct way to declare a char in an enum but
As you can see some values are integers and others are chars. However I am getting the following error when I try to place these values into a NSDicitonary like this
NSDictionary *iCTypes = [[NSDictionary alloc] initWithObjectsAndKeys:stDCMD,#"stMB", stMBMD,#"stMBMD", nil];
but I am getting this error below
Implicit conversion of 'int' to 'id' is disallowed with ARC
any help would be greatly appreciated.
An enum is basically an int type. Your enum definition is just fine. The problem is your use in the dictionary. You need to wrap the enum values in an NSNumber.
Try:
NSDictionary *iCTypes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:stDCMD], #"stMB", [NSNumber numberWithInt:stMBMD] ,#"stMBMD", nil];
or even better (using modern Objective-C):
NSDictionary *icTypes = #{ #(stDCMD) : #"stMB", #(stMBMD) : #"stMBMD" };
You need to store objects inside it, so you can't store an int, rather a NSNumber, which can be made by appending a # before the number constant:
NSDictionary *iCTypes = [[NSDictionary alloc] initWithObjectsAndKeys: #(stDCMD),#"stMB", #(stMBMD),#"stMBMD", nil];
However a clarification is needed on this:
First off I am not even sure if thats the correct way to declare a char in an enum but As you can see some values are integers and others are chars.
When you define an enum it stores integers, it doesn't matter if you set chars as values, they're compatible with int so the compiler will not complain. But the storage type is the same, they're still integers and any type compatible with integers will be accepted.
Both the objects and keys in an NSDictionary must be objects, and the keys specifically must be objects that conform to NSCopying. In order to use ints in an NSDictionary, you have to convert them to NSNumbers. You can use either [NSNumber numberWithInt:stDCMD] or, if you're using a newer version of Xcode, #(stDCMD).
In C char is a kind of short int.
enum can only hold integer types.
NSDictionary cannot hold C types. Only objects.
You can wrap your C types in NSValue or NSNumber to put in an NSDictionary.

Resources