The code is suppose to make a sound either yes or yes 3 play when clicked, but I get an error before I begin to debug that says rand cannot be statically allocated, but I can't put a * there because it's an integer. I am getting a conversion error when I do that. I also tried putting a * before sound, and that solved the error issue but when the button is clicked it wont play anything. So what do I do?
#import "ViewController.h"
#import <AVFoundation/AVAudioPlayer.h>
#interface ViewController ()
#end
#implementation
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}//this is where the error breakpoint is that you show me how to make
- (IBAction)Yes {
NSInteger rand = arc4random_uniform(2);
NSString sound = rand == 0 ? #"yes" : #"yes 3";
NSURL *url = [[NSBundle mainBundle] URLForResource:sound withExtension:#"mp3"];
AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[audioPlayer play];
}
#end
I've seen this many times before, and it has to do with the fact that your audio player variable is being released before it has a chance to play the file.
You need to create a property for the audio player in your header:
#property (nonatomic, strong) AVAudioPlayer *audioPlayer;
Then in your method access that property instead of the local variable:
- (IBAction)YES {
NSInteger rand = arc4random_uniform(2);
NSString *sound = rand == 0 ? #"yes" : #"yes 3";
NSURL *url = [[NSBundle mainBundle] URLForResource:sound withExtension:#"mp3"];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[self.audioPlayer play];
}
Note that this has absolutely nothing to do with the sound variable you're messing with. You should be using the * to indicate a pointer when creating that variable, as shown above.
I have the following code:
-(void) viewDidAppear:(BOOL)animated {
AsyncImageView *weatherImageView = [[AsyncImageView alloc] initWithFrame:weatherImage.frame];
NSString *myString = #"http://openweathermap.org/img/w/10d.png";
NSString *url = [NSString stringWithString:myString];
NSLog(#"The complete url is %#", url);
[weatherImageView loadImageFromURL:url];
[self.weatherImage addSubview:weatherImageView];
}
The image URL is all fine but the image does not show up when the view appears.
But if I write the following line in the same method
-(void) viewDidAppear: (BOOL) animated {
[self.weatherImage setImage:[UIImage imageNamed:[UIImage imageNamed:"background.png"]]];
}
I see that the image referred by "background.png" appears neat in the ImageView.
Wondering what is wrong with the first code.
loadImageFromURL expects a NSURL. Not a NSString:
AsyncImageView *weatherImageView = [[AsyncImageView alloc] initWithFrame:weatherImage.frame];
NSString *myString = #"http://openweathermap.org/img/w/10d.png";
NSURL *url = [NSURL URLWithString:myString];
NSLog(#"The complete url is %#", url);
[weatherImageView loadImageFromURL:url];
What's the best way to get an url minus its query string in Objective-C? An example:
Input:
http://www.example.com/folder/page.htm?param1=value1¶m2=value2
Output:
http://www.example.com/folder/page.htm
Is there a NSURL method to do this that I'm missing?
Since iOS 8/OS X 10.9, there is an easier way to do this with NSURLComponents.
NSURL *url = [NSURL URLWithString:#"http://hostname.com/path?key=value"];
NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];
urlComponents.query = nil; // Strip out query parameters.
NSLog(#"Result: %#", urlComponents.string); // Should print http://hostname.com/path
There's no NSURL method I can see. You might try something like:
NSURL *newURL = [[NSURL alloc] initWithScheme:[url scheme]
host:[url host]
path:[url path]];
Testing looks good:
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLWithString:#"http://www.abc.com/foo/bar.cgi?a=1&b=2"];
NSURL *newURL = [[[NSURL alloc] initWithScheme:[url scheme]
host:[url host]
path:[url path]] autorelease];
NSLog(#"\n%# --> %#", url, newURL);
[arp release];
return 0;
}
Running this produces:
$ gcc -lobjc -framework Foundation -std=c99 test.m ; ./a.out
2010-11-25 09:20:32.189 a.out[36068:903]
http://www.abc.com/foo/bar.cgi?a=1&b=2 --> http://www.abc.com/foo/bar.cgi
Here is the Swift version of Andree's answer, with some extra flavour -
extension NSURL {
func absoluteStringByTrimmingQuery() -> String? {
if var urlcomponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false) {
urlcomponents.query = nil
return urlcomponents.string
}
return nil
}
}
You can call it like -
let urlMinusQueryString = url.absoluteStringByTrimmingQuery()
Swift Version
extension URL {
func absoluteStringByTrimmingQuery() -> String? {
if var urlcomponents = URLComponents(url: self, resolvingAgainstBaseURL: false) {
urlcomponents.query = nil
return urlcomponents.string
}
return nil
}
}
Hope this helps!
What you probably need is a combination of url's host and path components:
NSString *result = [[url host] stringByAppendingPathComponent:[url path]];
You could try using query of NSURL to get the parameters, then strip that value using stringByReplacingOccurrencesOfString of NSString?
NSURL *before = [NSURL URLWithString:#"http://www.example.com/folder/page.htm?param1=value1¶m2=value2"];
NSString *after = [before.absoluteString stringByReplacingOccurrencesOfString:before.query withString:#""];
Note, the final URL will still end with ?, but you could easily strip that as well if needed.
I think -baseURL might do what you want.
If not, you can can do a round trip through NSString like so:
NSString *string = [myURL absoluteString];
NSString base = [[string componentsSeparatedByString:#"?"] objectAtIndex:0];
NSURL *trimmed = [NSURL URLWithString:base];
NSURL has a query property which contains everything after the ? in a GET url. So simply subtract that from the end of the absoluteString, and you've got the url without the query.
NSURL *originalURL = [NSURL URLWithString:#"https://winker#127.0.0.1:1000/file/path/?q=dogfood"];
NSString *strippedString = [originalURL absoluteString];
NSUInteger queryLength = [[originalURL query] length];
strippedString = (queryLength ? [strippedString substringToIndex:[strippedString length] - (queryLength + 1)] : strippedString);
NSLog(#"Output: %#", strippedString);
Logs:
Output: https://winker#127.0.0.1:1000/file/path/
The +1 is for the ? which is not part of query.
You might fancy the method replaceOccurrencesOfString:withString:options:range: of the NSMutableString class. I solved this by writing a category for NSURL:
#import <Foundation/Foundation.h>
#interface NSURL (StripQuery)
// Returns a new URL with the query stripped out.
// Note: If there is no query, returns a copy of this URL.
- (NSURL *)URLByStrippingQuery;
#end
#implementation NSURL (StripQuery)
- (NSURL *)URLByStrippingQuery
{
NSString *query = [self query];
// Simply copy if there was no query. (query is nil if URL has no '?',
// and equal to #"" if it has a '?' but no query after.)
if (!query || ![query length]) {
return [self copy];
}
NSMutableString *urlString = [NSMutableString stringWithString:[self absoluteString]];
[urlString replaceOccurrencesOfString:query
withString:#""
options:NSBackwardsSearch
range:NSMakeRange(0, [urlString length])];
return [NSURL URLWithString:urlString];
}
#end
This way, I can send this message to existing NSURL objects and have a new NSURL object be returned to me.
I tested it using this code:
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSURL *url = [NSURL URLWithString:#"http://www.example.com/script.php?key1=val1&key2=val2"];
// NSURL *url = [NSURL URLWithString:#"http://www.example.com/script.php?"];
// NSURL *url = [NSURL URLWithString:#"http://www.example.com/script.php"];
NSURL *newURL = [url URLByStrippingQuery];
NSLog(#"Original URL: \"%#\"\n", [url absoluteString]);
NSLog(#"Stripped URL: \"%#\"\n", [newURL absoluteString]);
}
return 0;
}
and I got the following output (minus the time stamps):
Original URL: "http://www.example.com/script.php?key1=val1&key2=val2"
Stripped URL: "http://www.example.com/script.php?"
Note that the question mark ('?') still remains. I will leave it up to the reader to remove it in a secure way.
We should try to use NSURLComponents
NSURL *url = #"http://example.com/test";
NSURLComponents *comps = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:YES];
NSString *cleanUrl = [NSString stringWithFormat:#"%#://%#",comps.scheme,comps.host];
if(comps.path.length > 0){
cleanUrl = [NSString stringWithFormat:#"%#/%#",cleanUrl,comps.path];
}
I think what you're looking for is baseUrl.
I'm pretty new to Objective C in general...
I'm wondering how I can use a *variable in the view controller, and add it onto the web view URL. Bellow is a UIWebViewer, It loads "site.com/something.php"... Along with that I would like for it to addon to the URL "?uuid=(UUID Variable here)".
Sorry... I'm more used to PHP/Perl coding where you can just throw in "$uuid"...
Thanks,
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *UUID = [[NSUUID UUID] UUIDString];
NSURL *myURL = [NSURL URLWithString:#"http://www.site.com/something.php?uuid="];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myURL];
[myWebView loadRequest:myRequest];
}
It's very simple you just need to create a property to assign whatever value you want to it
ViewController.m
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *uuid = [[NSUUID UUID] UUIDString]; // Convention says that UUID should uuid
// All we need to do now is add the uuid variable to the end of the string and we can do
// that by using stringWithFormat:
NSURL *myURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.site.com/something.php?uuid=%#", uuid]];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myURL];
[myWebView loadRequest:myRequest];
}
Check the documentation of NSString and the class method stringWithFormat:
Here's what you're looking for:
NSString *UUID = [[NSUUID UUID] UUIDString];
NSString *urlstr = [NSString stringWithFormat:
#"http://www.site.com/something.php?=%#", UUID];
NSURL *myURL = [NSURL URLWithString:urlstr];
NSString's stringWithFormat: method allows you to build strings from literal strings and varaibles. Variables are added to the literal string using format specifiers. Most of the format specifiers are the same as all the other C-based languages, %d for integer types, %f for floating types, %c for char, etc.
In the case of Objective-C, the %# is used as the place holder for objects that respond to the description selector, which returns a string. (In the case of an NSString, it just returns the string itself, but you'll notice that you can put lots of other types of objects in here too... in fact, every object that inherits from NSObject has a default description method).
I'm trying to use the "CocoaHTTPServer" found at https://github.com/robbiehanson/CocoaHTTPServer. I have added it to my project, and now, if i type on my browser something like this: 192.168.3.114:45000 i receive an html page called index with a simple welcome message (this page is stored inside the default project). This is ok. It works correctly. What i need to understand now, is how can i for example do a simple GET request typing on the browser something like "192.168.3.114:52000/getElement" and receive on the browser a simple String. Can you please give me help? I don't know where i can configure or check this because there are some classes. I'm trying to study the HTTPConnection class but i'm going in confusion because i'm new on the objective-c programming.
Thanks
You have to use a custom HTTPConnection subclass
#interface MyHTTPConnection : HTTPConnection
...
#end
then you could do custom URL handling
#implementation MyHTTPConnection
- (NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path
{
HTTPLogTrace();
if ([path isEqualToString:#"/getElement"])
{
NSData *data = ...
HTTPDataResponse *response = [[HTTPDataResponse alloc] initWithData:data];
return response;
}
// default behavior for all other paths
return [super httpResponseForMethod:method URI:path];
}
#end
and the set HTTPServer connectionClass so that your server knows you want to handle the connections yourself
[httpServer setConnectionClass:[MyHTTPConnection class]];
You can do an NSURL request and then get the server response as an NSString:
NSString *URL = #"http://yoururlhere.com?var1=";
URL = [URL stringByAppendingString: yourvarstring];
NSData *dataURL = [NSData dataWithContentsOfURL: [ NSURL URLWithString: URL]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
//Check if the server has any output
if([serverOutput length] == 0)
{
//Do something
} else {
//Do Something else
}