I am just learning Objective-C from the couple of days and I am confused with NSURL. Here is my code
NSString *n = [NSString stringWithFormat:#"%#",#"http://somedomain.com/api/x?q={\"order_by\":[{\"field\":\"t\",\"direction\":\"desc\"}]}"];
NSURL *url = [[NSURL alloc ]initWithString:n];
NSLog(#"%#",url);
But when I trying to print an url value its null.
It seems no problem when I try to init url without JSON parameter in url.
Can I get some explanation where my problem is?
NSString *n = [NSString stringWithFormat:#"%#",#"http://somedomain.com/api/x?q={\"order_by\":[{\"field\":\"t\",\"direction\":\"desc\"}]}"];
NSURL *url = [NSURL URLWithString:[n stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"%#",url);
The proper way to compose a URL from strings is to use NSURLComponents helper class.
The reason for this seemingly elaborate approach is that each component of a URL (see RFC 3986) requires slightly different percent encodings or possibly none.
The exact structure of the query component is not defined in RFC 3986, though. Usually, its an array of key/value pairs that will be escaped as described at w3.org: x-www-form-urlencoded-encoding-algorithm. NSURLComponents provides a method to encode the query component as well.
Related
I am integrating PayTm with my app and I want to pass the parameters using GET method.
My code is as follows:
NSString *urlString = [NSString stringWithFormat:#"https://secure.paytm.in/oltp/HANDLER_INTERNAL/TXNSTATUS?JsonData={%22MID%22:%22%#%22,%22ORDERID%22:%22a84afd6c-0e54-42df-b29a-2b057f9e7c53%22}",MIDValue];
where MIDValue is a string.
When I use this code I'm getting error message.
Please give a suggestion to remove the error.
Thank You
Maybe your variable MIDValue contains space and/or &.
You first have to encode it as URL and then pass it as parameter.
Visit this for details, I guess this is what you are looking for
NSString *newParam = [MIDValue stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]
NSString *urlString = [NSString stringWithFormat:#"https://secure.paytm.in/oltp/HANDLER_INTERNAL/TXNSTATUS?JsonData={%22MID%22:%22%#%22,%22ORDERID%22:%22a84afd6c-0e54-42df-b29a-2b057f9e7c53%22}", newParam];
I have one string. Now I wanted to split this string. For static separation I know the code but I don’t code for dynamic value.
my string is
NSString *str = #"https://graph.facebook.com/v2.5/181054825200000/feed?fields=created_time,message,picture,full_picture,comments.limit%280%29.summary%28true%29,likes.limit%280%29.summary%28true%29&limit=5&format=json&access_token=CAALjFrE5mNYBAOg1EDiUrsE2kr1kIRrLIv7g4OweSMvHso2exB5Dttshn7dgOlW24ZCXSnDZAWiV6xMUKXedTXUhiHpdmZBPCGzD1orFlrLRP2gaBZCbZBZBnjUHewF9hZBmJKxtiwVzpw9gnnQXk5Hfx0ZBM2ksAUzkSWR5feaNMbf3UUmUpJlxeh0gKdDrzWBvIJRPy0xGqL0ZAMFsRhyCZCTX42l1sZAceZB0VCeDZB95mrAZDZD&until=1456345291&__paging_token=enc_AdCKD3tSYMoZB3MCKaJkYnbVmBgUyY2tBceGDD2G1hqxRDiQKZCsSbmvWZASLvlCMf0BVzq2uZAScSWp7ZAavZB2d72BIHJISefk09noRuv9gA5b5hFwZDZD";
but i don’t how to show any value dynamically .(for e.g. until (in string))
please help me for this issue.
Thank You.
If you are parsing a URL you should really use NSURLComponents. It makes breaking a URL into the different parts much easier, and the code is tested and verified by Apple.
For separate string by a separator you can use this.
NSString *url = #"<url>";
NSArray *array = [url componentsSeparatedByString:#"<seperator string>"];
NSLog(#"%#", array);
But for URL parsing ,As per Duncan's answer, yes it is good to parse a URL using NSURLComponents. By using this class you can get any desired part of an URL.
I'm trying to add a base url for my networking code, the problem is that this URL gets broken when passing to the URLWithString:relativeToURL: method. This URL has the port i'm using, however, after calling the described, the URL is wrong, not including my current port number. I think this is a problem with percent escapers, but i've tried some methods to solve this problem without success.
Here is my code:
// absolute string returns a url a with broken path
[[NSURL URLWithString:#"api/whatever" relativeToURL:[NSURL URLWithString:#"193.178.0.99:9000"]] absoluteString]
// printed absolute path 193.173.0.99:///api/whatever
Other tried approaches:
NSString *baseURLString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)#"193.178.0.99:9000",NULL,(CFStringRef)#":",kCFStringEncodingUTF8);
[[NSURL URLWithString:#"api/whatever" relativeToURL:[NSURL URLWithString:baseURLString]]
// Printed path : 193.173.0.99%3A8000/api/whatever, this path is still not working, although i have the percent escape set.
NSString *baseURLString = [#"193.173.0.99:8000" stringByAddingPercentEscapesUsingEncoding : NSUTF8StringEncoding];
// ... The same final code from above.
// Printed -> the very same first result.
EDIT : From the comment above the URLWithString:relativeToURL: : "These methods expect their string arguments to contain any percent escape codes that are necessary."
Does anybody have a solution to this problem ?
Thanks.
Actually the solution is pretty simple... just add the scheme.
Something like this:
NSURL *baseURL = [NSURL URLWithString:#"http://193.178.0.99:9000"];
NSString *absoluteString = [[NSURL URLWithString:#"api/whatever" relativeToURL:baseURL] absoluteString];
// Prints => http://193.178.0.99:9000/api/whatever
That behavior is actually quite understandable (from an RFC point of view): the relativeToURL part is expected to be a full-fledged URL root, including the URL scheme.
So here in your example, as you didn't provide an http:// scheme or similar, 193.178.0.99 is considered to be the scheme — like it would be http or https or ftp or tel or mailto — and the 9000 port considered to be the host part of your URL (but as 9000 is probably not a valid host according to the RFC, it's probably why you have the warning by the way)
In a way, 193.178.0.99:9000 is interpreted in a similar manner a phone-number URL tel:1-541-754-3010 or a mail URL mailto:john.doe#nowhere.com would; the : separating the URL scheme from the host, not separating the host from the port.
To solve this, simply include the URL scheme (like http or https or whatever the protocol you intend to use) in the relativeToURL parameter:
[[NSURL URLWithString:#"api/whatever"
relativeToURL:[NSURL URLWithString:#"http://193.178.0.99:9000"]]
absoluteString]; // ^^^^^~~ this is the important part
Note: as an alternate solution to build your URL, you could use the iOS7's NSURLComponents class to manipulate NSURL parts separately, that's another way to break down and build up URLs
The docs for NSURL state that:
An NSURL object represents a URL that can potentially contain the
location of a resource on a remote server, the path of a local file on
disk, or even an arbitrary piece of encoded data.
I have a blob of in-memory data that I'd like to hand to a library that wants to load a resource via an NSURL. Sure, I can first write this NSData to a temp file and then create a file:// NSURL from that, but I'd prefer to have the URL point directly to the buffer that I already have present in memory.
The docs quoted above seem to suggest this is possible, but I can't find any hint of how to accomplish it. Am I missing something?
NSURL supports the data:// URL-Scheme (RFC 2397).
This scheme allows you to build URLs in the form of
data://data:MIME-Type;base64,<data>
A working Cocoa example would be:
NSImage* img = [NSImage imageNamed:#"img"];
NSData* imgData = [img TIFFRepresentation];
NSString* dataFormatString = #"data:image/png;base64,%#";
NSString* dataString = [NSString stringWithFormat:dataFormatString, [imgData base64EncodedStringWithOptions:0]];
NSURL* dataURL = [NSURL URLWithString:dataString];
Passing around large binary blobs with data URLs might be a bit inefficient due to the nature of base64 encoding.
You could also implement a custom NSURLProtocol that specifically deals with your data.
Apple has some sample code that uses a custom protocol to pass around image objects: https://developer.apple.com/library/mac/samplecode/SpecialPictureProtocol/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003816
What you are missing is the NSURLProtocol class. Takes about three dozen lines of code, and any code that handles URLs properly can access your in-memory data. Read the documentation, it's not difficult and there is sample code available.
Unfortunately there are some APIs that take an NSURL as a parameter, but can only handle file URLs.
In my code I have to use URLWithString to play streaming(HLS) video and fileURLWithPath to play local video.
What is the difference between these two methods?
How should I use single method to play both videos.
Also I need to show last frame as still image when HSL video ends. Its now showing blank screen when it ends. How should i achieve this?
+URLWithString: produces an NSURL that represents the string as given. So the string might be #"http://www.google.com" and the URL represents http://www.google.com.
+fileURLWithPath: takes a path, not a URL, and produces an NSURL that represents the path using a file:// URL. So if you give it /foo/bar/baz the URL would represent file:///foo/bar/baz.
You can of course construct a file URL string manually and pass it to +URLWithString:, but +fileURLWithPath: is simpler to use when you already have a path, as you don't have to deal with escaping the string and coercing it to a URL format.
Similar thing happened in my app which use AVAudioPlayer. I tried with [NSURL URLWithString:path] and found out it fails to open certain mp3 files. I looked into error by a line like [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] fileTypeHint:AVFileTypeMPEGLayer3 error:&error], but the error was simply nil
However it was resolved by replacing the url with [NSURL fileURLWithPath:path].
In both case, the path path NSString * #"/var/mobile/Containers/Data/Application/4D96D4AE-2ED4-40B0-85D2-230E1AFA90E7/Documents/01-AudioTrack 01.mp3" 0x1457a8f0 Still I don't know the reason but now I should be careful using [NSURL URLWithString:].
PS. In NSURL Reference document, Apple said as below:
IMPORTANT
To create NSURL objects for file system paths, use fileURLWithPath:isDirectory: instead.
which clearly indicates [NSURL fileURLWithPath:] should be used for open file, though [NSURL URLWithString] also works for some cases.