Display NSMutableArray objects as text in UITextView - ios

Hey I am trying to display objects from NSMutableArray as text in UITextView and I am getting a problem:
Invalid operands to binary expression ('void' and 'NSString *')
Any suggestions how can it be done?
Here is the Code:
for (id obj in Mview.arrayTape)
viewTape.text = Mview.arrayTape.removeLastObject + #"/n" + viewTape.text;
viewTape is an UITextView , arrayTape is the NSMutableArray passed from another view
Any help would be much appreciated.

removeLastObject returns nothing (void) and you are appending it result to make a new string:
viewTape.text = Mview.arrayTape.removeLastObject + #"/n" +
viewTape.text;
Try this instead: (untested)
for (NSString* obj in Mview.arrayTape)
{
viewTape.text = [viewTape.text stringByAppendingFormat:#"%#\n", obj];
}
Assuming obj is a type of NSString, if it is not use its corresponding string representation.
EDIT
Another approach. not yet offered by other solutions, no need to use for loop
viewTape.text = [Mview.arrayTape componentsJoinedBy:#"\n"]

Mview.arrayTape.removeLastObject has the return type void i.e. it does not have a return value. And you cannot concatenate nothing with a string because void does not have a type (or class).
I guess what you want is this:
viewTape.text = [NSString stringWithFormat:#"%#\n%#",(NSString *)Mview.arrayTape.lastObject,viewTape.text];
You can remove the last object afterwards if intended:
[Mview.arrayTape removeLastObject];

It is because this method removeLastObject do not returns anything, look here. You should get the last object and get the string value add it (append it) to text in text view and the remove if required

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.

can I switch NSString

I want to switch NSString in XmlParser because if there are 15 or more web-service then every time the loop check for correct element in IF..ELSE.That I don't want to make processor busy..
I have searched a lot and found using enum I can switch NSString but no luck ..
I have tried each possibilities,but some where i am making mistake.
Please help to solve this big problem for me.
Here I have declare my enum:
Here in "elementName" I am getting Exact value as declared in enum:
But instead of 1, I am getting wrong value Like 202896536:
You cant do it by creating enum. You must need to compare the string.
if([elementName isEqualToString:#"UserLoginComplexType"])
//Do something...
You can not cast a string to ENUM value, you will need to parse it, ENUM values are integers not strings.
You will have to use an if statement.
You could use a helper method:
WebServiceList.h
typedef NS_ENUM(NSUInteger, WebServiceList) {
WebServiceListNone = 0,
UserLoginComplexType = 1,
RegisterUserResult = 2,
RecoverPasswordResult = 3,
....
};
FOUNDATION_EXTERN WebServiceList WebServiceListForString(NSString *string);
WebServiceList.m
WebServiceList WebServiceListForString(NSString *string) {
WebServiceList list = WebServiceListNone;
if (![type isKindOfClass:[NSString class]]) {
return CallRecordTypeNone;
}
else if ([string isEqualToString:#"UserLoginComplexType"] {
list = UserLoginComplexType;
}
else if ([string isEqualToString:#"UserLoginComplexType"]) {
list = UserLoginComplexType;
}
else .....
return list;
}
As seen in your commented codes, you're parsing a XML and saving in a NSMutableArray named arrProductList in App Delegate.
After finishing the parsing of XML, the variable should contain the data in array. You should look into the variable & fetch the corresponding value. Since you didn't post any further details about parsing / XML structure, I'm unable to write some codes related to result fetching.
For easy readability and to avoid lots of if-else statements, I like to do mine as a dictionary:
(also makes it easy to update in the future when you add more to your enum)
NSString* elementName = ...;
// Default value
WebServiceList value = UserLoginComplexType;
NSDictionary* stringToEnum = #{#"UserLoginComplexType":#(UserLoginComplexType),
#"RegisterUserResult":#(RegisterUserResult),
#"RecoverPasswordResult":#(RecoverPasswordResult)};
NSNumber* enumValue = stringToEnum[elementName];
if(enumValue != nil)
value = (WebServiceList)enumValue.integerValue;

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];

ios assigning value to a string from an array

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];

Resources