URL encode string in ios failing - ios5

I am trying to url encode a string in my iOS 5 app using ARC.
This is how i do it:
- (NSString *)escape:(NSString *)text
{
return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(__bridge CFStringRef)text, NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8);
}
I then call it with test data like this:
NSLog([self escape:#"kalel///&&&???"]);
But the output i get from the NSLog is this:
kalel0.0000000.0000000.00000022623F0.0000000.000000
That just does not seem right, but no matter what I can't get it right

Your escape function is fine. The problem is in a way you call NSLog:
escape produces the string kalel%2F%2F%2F%26%26%26%3F%3F%3F for your input. NSLog interprets this string as a format string and prints some garbage as floating point numbers right after kalel word!
You should always call NSLog with a string constant as a first argument, e.g.:
NSLog(#"%#", [self escape:#"kalel///&&&???"]);
P.S. You have a memory leak in escape --- you should return (__bridge_transfer NSString *) as you transfer retained CF object to Objective C space.

Related

Getting NSString from char * (Converting C's char-pointer)

I want to show the char * in the UITextField
What I tried:
char *data;
char *name=data+6;
txtName.text=[[NSString alloc] initWithCString:name encoding:NSUTF8StringEncoding];
but I am not getting the correct value.
To create an NSString from a const char *, simply use these methods:
Returns an autoreleased object:
/**
* Should be wrapped in `#autoreleasepool {...}`,
* somewhere not far in call-stack
* (as closer it's, the lower our memory usage).
*/
NSString *stringFromChar(const char *input) {
return [NSString stringWithUTF8String: input];
}
Whenever we return an object (maybe to Swift), we need to register into nearest #autoreleasepool block (by calling autorelease method to prevent memory-leak, according to ownership-rules), but ARC does that automatically for us.
But even with ARC disabled, we are NOT forced to call autorelease manually, like:
return [[NSString stringWithUTF8String: name] autorelease];
Generally, convenience factory methods (like stringWithUTF8String:), already call the autorelease method (or should if ARC disabled), because the class simply does not intend to own the instance.
Creates a retained object:
NSString *result = [[NSString alloc] initWithUTF8String: name];
// ... Do something with resulted object.
// NOTE: calling below is not required
// (If ARC enabled, and should cause compile error).
[result release];
Update 2021 about difference; With ARC enabled, these two methods are equivalent (i.e. ARC will auto-call autorelease method; always registering to nearest #autoreleasepool).
Reference.
If you are not getting the correct value, then something is wrong with the data. Add a few NSLog calls to see what the strings contain.
What do you expect? You have an uninitalized char*. Then you add 6 to the pointer, which is already undefined behaviour. Then you try to turn a pointer pointing to any old rubbish (and you have no idea where it is pointing) to an NSString*. Nothing good can come from this.
Define a char* pointing to an actual, real C string using ASCII or UTF-8 encoding. Then create an NSString like this:
char* cstring = "Try harder";
NSString* objcstring = #(cstring);
You can use [NSString stringWithUTF8String: data].

creating an http body with construction method

I am trying to create a http body that I am going to pass in using NSURLRequest post.
I have my connection class all set up.
The thing is i have several methods that return NSStrings and UInt32's and one construction method that I want to use to put all of these methods into one http body which will be of data type format.
However I'm not sure how to call these methods that return the correct data from my construction method to gather the data into one data object.
here is some code that I have (shortened so its a little clearer)
these methods are used to return the data needed
- (UInt32) addDataVer
{
UInt32 dataVer = 0;
return dataVer;
}
- (NSString *) addReg
{
NSString *reg = [[NSString alloc] initWithString:#"abcd1"];
return reg;
}
- (NSString *) addActiv
{
NSString *activ = [[NSString alloc] initWithString:#"abcd2"];
return activ;
}
from here I'm not sure what to do, or how to get the data. I have created a construction method, that I want to use to grab the data and then I want to use that data to build a NSData object where I put the returning data into it in order.
this is my construction class
- (void) constructRequest
{
//what the heck do I call in here? lol
}
the last thing I will have to do is figure out how to put the nsdata representation of each return value into the data object... if that makes sense...
any help would be appreciated.
UPDATE::
So I figured out how to get the return value into my construction method, by following the force!
- (void) constructRequest
{
NSString *mystring = [[NSString alloc] initWithString:[self addReg]];
NSLog(#"mystring %#", mystring);
}
however I am not sure how to do this with a returning UInt32, or how to convert this in to a NSData structure
From Apple Docs on String formatting https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1
[NSString stringWithFormat:"my unsigned 32-bit int: %d", [self addDataVer]];
from Apple Docs about NSString class
To convert your entire string to data:
[myNSString dataUsingEncoding:NSUTF8StringEncoding];

What is the difference between NSString = #"HELLO" and NSString getting that same string using initWithContentsOfURL

I have a string that is getting the content from URL and when I try to use it, it doesn't work the way I thought it should.
When I initialize NSString with with contents of URL like this:
NSString *strFromURL = [[NSString alloc] initWithContentsOfURL:someURLReturningTextHELLO encoding:NSUTF8StringEncoding error:nil];
NSLog(#"%#",strFromURL); // returns "HELLO" // as expected
but when I try:
if (strFromURL == #"HELLO") { NSLog(#"IT WORKS"); } // This doesn't happen
When I do the same process with:
NSString *mySimpleString = #"HELLO";
if (mySimpleString == #"HELLO") { NSLog(#"IT WORKS"); } // This works
So, my question is, how can I get content from URL that I can use later in my IF statement?
*I'm new to Objective-C. Thanks!
When you asking for if (strFromURL == #"HELLO") you're comparing equality of objects, but not strings. When you call comparison of two constant strings it works, other it fails whether strings in compared objects are equal or not.
Call if ([strFromURL isEqualToString:#"HELLO"]) instead.
With objects, the == operator tests for pointer equality. That is, the two variables are the same if the pointers both point to the same object. The string fetched from the URL is not the same object as the constant string, so it fails. You want to use NSString's isEqualToString: method, which tests for whether the strings themselves are equal rather than the pointers.
You can try to compare with a isEqualToString method

deleteCharactersInRange work something wrong

HI all! I am using message deleteCharactersInRange from NSMutableString. And there is a problem that this finction deletes range in a wrong way.
Here is a sample of code that works wrong:
-(void) btnClick
{
NSRange deleteRange = NSMakeRange(0, 1);
[valueStr deleteCharactersInRange:deleteRange];
[self ShowNumber];
}
I have a mutable string: "-21.256" and when I press the button btnClick it must delete "-" from the begining but it does it only after the 5th presses time. Ealier it worked fine, but now no. Help please, or what can I use instead this function? Thanx!
Your code should work just fine:
NSMutableString *string = [NSMutableString stringWithString:#"-21.256"];
NSLog(#"%#", string);
[string deleteCharactersInRange:NSMakeRange(0, 1)];
NSLog(#"%#", string);
results in:
-21.256
21.256
Your problem must be elsewhere.
I think it will be interesting to you.
I itinialized my string in a such way:
NSString *buf = nil;
buf = [NSString stringWithFormat:#"%14.5f", myCalculator.calcValue];
after that I add this string to my NSMutableString. And with string I did operations with the help of func:
[string deleteCharactersInRange:NSMakeRange(0, 1)];
But charachters were deleted only after the 6 or 7 cycle of clicking.
Solution:
The problem is in #"%14.5f" in this string we have:
" -2.00000"instead of "-2.00000" so function does her work well, but it deleted white spaces instead of "-".
So we need to convert in such way: #"%f"

what is the exact meaning of "message" in this line on iphone

NSDictionary *story = [stories objectAtIndex: indexPath.row];
cell.text=[NSString stringwithFormat:[story objectForKey#"message];
i dont knw what exaclty "message " contains (what is the meaning of objectForKey#"message")
EDIT CODE
NSString *key =[appDelegate.books objectAtIndex:indexPath.row];
//dict y=#"Name";
NSArray *nameSection = [dict objectForKey:key];
NSDictionary *story = [nameSection objectAtIndex: indexPath.row];
cell.text=[NSString stringwithFormat:[story objectForKey:key]];
NSLog(#"Value Of message: %#", [dict objectForKey:key]);
why my code crashes
If you are more familiar with Java or C# the code is equivalent to something like this:
// Assuming stories is declared as: List<Dictionary<string, string> stories;
Dictionary<string, string> story = stories[indexPath.row];
cell.Text = String.Format(story["message"]);
In Smalltalk-style (and therefore Objective-C too) Object Oriented programming, methods are more like messages to other objects. So a good Objective-C method name should read like an English sentence (Subject-Verb-Object). Because of this working with dictionaries (hash tables) looks like this:
[myDictionary setObject:#"Value" forKey:#"someKey"];
[myDictionary objectForKey:#"someKey"]; // == #"Value"
In Java it would be:
myDictionary.put("someKey", "Value");
myDictionary.get("someKey"); // == "Value"
Notice how the key ("someKey") was the first argument in the Java example. In Objective-C you name your arguments with the method name, hence setObject: forKey:. Also notice that in Objective-C strings start with an # symbol. That's because Objective-C strings are different from regular C strings. When using Objective-C you almost always use Objective-C's # strings.
In C# there is a special syntax for Dictionaries so it becomes:
myDictionary["someKey"] = "Value";
myDictionary["someKey"]; // == "Value"
One important problem that you might encounter if you're new is the problem of native types.
In Java to add an int to a Dictionary you used to have to do:
myDictionary.put("someKey", new Integer(10));
Because the primitive types (int, char/short, byte, boolean) aren't real Objects. Objective-C has this problem too. So if you want to put an int into a dictionary you must use NSNumber like so:
[myDictionary setObject:[NSNumber numberForInt:10]
forKey:#"someKey"];
And you pull out the integer like so:
NSNumber *number = [myDictionary objectForKey:#"someKey"];
[number intValue]; // == 10
EDIT:
Your code might be crashing if you have a '%' character in your string, since stringWithFormat is just like NSLog in that it takes many arguments. So if story["message"] is "Hello" then it'll work fine without extra arguments but if it's "Hello %#" you need to add one argument to stringWithFormat.
NSString *message = #"Hello %#";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:message forKey:#"message"];
NSString *output = [NSString stringWithFormat:[dict objectForKey:#"message"], #"World!"];
// output is now #"Hello World!".
#"message" is a key for a value stored in the NSDictionary object. The first line declares an NSDictionary named story that appears to come from an array.
If you want to find what value is stored for the key:#"message", consider using:
NSLog(#"Value Of message: %#", cell.text);
Run and check the console to see the output. (SHIFT + COMMAND + Y) in XCode will bring up the console, if that's what you are using. If you are unfamiliar with NSArrays/NSDictionaries, give Apple's Documentation a look.
I'm just guessing at all of this since that is a very limited sample of code. Try submit more code when you ask a question so that the viewers can get a better idea of your questions.
That is an example of key-value coding, and a lot of information is available on the Apple dev site if you're interested:
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html