NSString Somehow turn in to an "__NSArrayI" object - objective-c

i am receiving response from my server, it looks like this :
2012-09-12 16:29:11.690 WhatIsIt[1763:707] (
{
qid = ebb81a9c0c2125c9f12fee33c281dfe2ef5c1596;
"qid_data" = {
labels = Wristwatch;
};
} )
when i am parsing the "qid" value like this :
- (void)updateCompleteWithResults:(NSArray*)results{
NSLog(#"%#",results);
NSString *qid = [results valueForKey:#"qid"];
the NSString object is getting a Parentheses around the string (i dont know how)
looks like this :
2012-09-12 16:34:17.979 WhatIsIt[1785:707] (
2e1da5854f3b4f02cd967293cd1364e6d3e0b76a
)
so i tried to use :
NSString *string = #" spaces in front and at the end ";
NSString *trimmedString = [string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
and the app crashes, any idea?

The problem is the root object of this structure is an array...
If you look at the valueForKey: method on NSArray you'll see that it will actually call valueForKey: on each of it's members and return the results in another array (this is what you are seeing).
What you should do instead is first get the object you are interested in and then work with it on it's own
NSDictionary *myObject = [whatIsIt objectAtIndex:0];
NSString *qId = [myObject objectForKey:#"qid"];

Related

Got an error when try to print stringByReplacingOccurrencesOfString method

When i try to print this string i got bad access error:
NSString *myPath = [myPath stringByReplacingOccurrencesOfString:#"/Users/Me/Library/iPhone/4.2/MyApp/Documents/Photos/pic1.png"
withString:#"/Users/John/Library/iPhone/5/MyApp/Documents/Photos/picture.png"];
NSLog(#"%#", myPath);
Why?
Thanks.
The error is because you are calling the method stringByReplacingOccurrencesOfString:withString on a variable (myPath) that has not been instantiated. You need to call that method on an instance of the NSString class that already contains the string you are replacing text in.
When you call a method you call it on the receiver. Therefore you are calling stringByReplacingOccurrencesOfString:withString: on myPath.
You are assigning the value of the method into
NSString *myPath
which makes me assume that the myPath in
[myPath ....
is not actually set to anything. (potentially pointing to garbage)
What you want is something like this
NSString *startString = #"hello";
// Receiver Message
// | |
// v v
NSString *replacedString = [startString stringByReplacingOccurrencesOfString:#"hello"
withString:#"bye bye"];
NSLog(#"Results in => %#", replacedString);
// Output
2011-12-11 20:50:01.964 Untitled 2[779:707] Results in => bye bye
In your above comment you tried NSString *myPath = [[NSString alloc] init]; this would create an empty string. An empty string does not contain any occurrences of #"/Users/Me/Library/iPhone/4.2/MyApp/Documents/Photos/pic1.png" therefore it can't replace them.

Converting NSString to key value pair

I have a response from server which is NSString and looks like this
resp=handshake&clientid=47D3B27C048031D1&success=true&version=1.0
I want to convert it to key value pair , something like dictionary or in an array .
I couldn't find any useful built-in function for decoding the NSString to NSdictionary and replacing the & with space didn't solve my problem , can anyone give me any idea or is there any function for this problem ?
This should work (off the top of my head):
NSMutableDictionary *pairs = [NSMutableDictionary dictionary];
for (NSString *pairString in [str componentsSeparatedByString:#"&"]) {
NSArray *pair = [pairString componentsSeparatedByString:#"="];
if ([pair count] != 2)
continue;
[pairs setObject:[pair objectAtIndex:1] forKey:[pair objectAtIndex:0]];
}
or you could use an NSScanner, though for something as short as a query string the extra couple of arrays won't make a performance difference.

Displaying the contents of an NSMutableArray in a UITextView

I have this array, NSSMutableArray *myarray, which has five objects in it, and I am using a loop like this:
for( className *myObject in myarray)
{
myTextview.text = [NSString stringWithFormat:#"the name is %#", myObject];
}
When I build and run, only the last name shows in my UITextView *myTextview. I logged it, and my loop is working fine -- it's showing all five objects.
The problem seems to be that each time an object is sent to the myTextView, the next object replaces it; is there a way I can hold all of them, so the whole array can be shown?
Each time you pass the loop you are replacing myTextview.text. What you want is to add to the string each time. Try this:
NSMutableString *string = [NSMutableString string];
for( className *myObject in myarray) {
[string appendString:[NSString stringWithFormat:#"the name is %#\n", myObject]];
}
myTextview.text = string;

How do you enumerate through an array in Obj-C?

I have an array which has several objects (all of different classes) in it. But using enumeration doesn't work on it for some reason.
NSString *arrayString;
NSURL *arrayUrl;
NSProcessInfo *arrayPr;
NSDictionary *arrayDictionary;
NSMutableString *arrayMString;
NSMutableArray *objectArray = [NSMutableArray arrayWithObjects:arrayString,arrayUrl,arrayPr,arrayDictionary,arrayMString,nil];
for( NSString *item in objectArray ){
NSLog(#"Class name is: %#", [item className]);
}
I think it might be something to do with how the objects are been added to the array but i'm new to objective-c and not sure.
you aren't actually populating the array.
NSString *arrayString;
declares a variable, arrayString, of type NSString. it's not initialized (so it deserves to crash when you use the variable -- but may be 0 with some build settings).
so, to assign a variable:
NSString *arrayString = [NSString stringWithFormat:#"sksjdhf %f\n", 3.3];
arrayWithObjects adds objects from the (va list) argument until nil/null/0 is encountered.
you must set up the remainder of your variables/arguments correctly before using them.
this should work as you expect it to:
NSString * str = #"a string";
NSMutableArray *objectArray = [NSMutableArray arrayWithObjects:str, nil];
for (NSObject * item in objectArray) {
NSLog(#"Class name is: %#", [item className]);
}
In the for loop, use an id data type. The id data type is a general purpose data type that can be used to store a reference to any object.
For example:
for ( id item in objectArray ) {
NSLog(#"Class name is: %#", [item className]);
}
Yep, that's how you do it. If you're having trouble, it is not in the enumeration syntax itself.

How to check if NSString begins with a certain character

How do you check if an NSString begins with a certain character (the character *).
The * is an indicator for the type of the cell, so I need the contents of this NSString without the *, but need to know if the * exists.
You can use the -hasPrefix: method of NSString:
Objective-C:
NSString* output = nil;
if([string hasPrefix:#"*"]) {
output = [string substringFromIndex:1];
}
Swift:
var output:String?
if string.hasPrefix("*") {
output = string.substringFromIndex(string.startIndex.advancedBy(1))
}
You can use:
NSString *newString;
if ( [[myString characterAtIndex:0] isEqualToString:#"*"] ) {
newString = [myString substringFromIndex:1];
}
hasPrefix works especially well.
for example if you were looking for a http url in a NSString, you would use componentsSeparatedByString to create an NSArray and the iterate the array using hasPrefix to find the elements that begin with http.
NSArray *allStringsArray =
[myStringThatHasHttpUrls componentsSeparatedByString:#" "]
for (id myArrayElement in allStringsArray) {
NSString *theString = [myArrayElement description];
if ([theString hasPrefix:#"http"]) {
NSLog(#"The URL is %#", [myArrayElement description]);
}
}
hasPrefix returns a Boolean value that indicates whether a given string matches the beginning characters of the receiver.
- (BOOL)hasPrefix:(NSString *)aString,
parameter aString is a string that you are looking for
Return Value is YES if aString matches the beginning characters of the receiver, otherwise NO. Returns NO if aString is empty.
As a more general answer, try using the hasPrefix method. For example, the code below checks to see if a string begins with 10, which is the error code used to identify a certain problem.
NSString* myString = #"10:Username taken";
if([myString hasPrefix:#"10"]) {
//display more elegant error message
}
Use characterAtIndex:. If the first character is an asterisk, use substringFromIndex: to get the string sans '*'.
NSString *stringWithoutAsterisk(NSString *string) {
NSRange asterisk = [string rangeOfString:#"*"];
return asterisk.location == 0 ? [string substringFromIndex:1] : string;
}
Another approach to do it..
May it help someone...
if ([[temp substringToIndex:4] isEqualToString:#"http"]) {
//starts with http
}
This might help? :)
http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/characterAtIndex:
Just search for the character at index 0 and compare it against the value you're looking for!
This nice little bit of code I found by chance, and I have yet to see it suggested on Stack. It only works if the characters you want to remove or alter exist, which is convenient in many scenarios. If the character/s does not exist, it won't alter your NSString:
NSString = [yourString stringByReplacingOccurrencesOfString:#"YOUR CHARACTERS YOU WANT TO REMOVE" withString:#"CAN either be EMPTY or WITH TEXT REPLACEMENT"];
This is how I use it:
//declare what to look for
NSString * suffixTorRemove = #"</p>";
NSString * prefixToRemove = #"<p>";
NSString * randomCharacter = #"</strong>";
NSString * moreRandom = #"<strong>";
NSString * makeAndSign = #"&amp;";
//I AM INSERTING A VALUE FROM A DATABASE AND HAVE ASSIGNED IT TO returnStr
returnStr = [returnStr stringByReplacingOccurrencesOfString:suffixTorRemove withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:prefixToRemove withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:randomCharacter withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:moreRandom withString:#""];
returnStr = [returnStr stringByReplacingOccurrencesOfString:makeAndSign withString:#"&"];
//check the output
NSLog(#"returnStr IS NOW: %#", returnStr);
This one line is super easy to perform three actions in one:
Checks your string for the character/s you do not want
Can replaces them with whatever you like
Does not affect surrounding code
NSString* expectedString = nil;
if([givenString hasPrefix:#"*"])
{
expectedString = [givenString substringFromIndex:1];
}