Using AVAudioPlayer in iOS5? - avaudioplayer

So I'm trying to play a .wave file in iOS5, and I'm getting a warning, which is leading to SIGABRTs and generally not-working code.
NSURL *soundUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/Resources/Sounds/01_main_menu_list.wav", [[NSBundle mainBundle] resourcePath]]];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
[_audioPlayer setDelegate:self];
[_audioPlayer play];
This is giving me an error "Sending "ViewController *const __strong" to parameter of incompatible type 'id '.
I have literally no idea why, I've followed a half-dozen examples and am coming up empty. I'd love a pointer in the right direction.

This should work:
NSURL* soundUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"01_main_menu_list" ofType:#"wav"]];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
audioPlayer.delegate = self;
[audioPlayer play];
If not, I think there's something wrong with the wav file. Maybe the encoding?

Turned out it was an issue with ARC releasing, I fixed it by adding a #property and #synthesize pair for the AVAudioPlayer in question, and declaring it as strong. It got rid of all of these errors, and played the file with no problems.

Related

Having trouble in converting data into NSString from NSData

I want to convert NSData into NSString, my code is below.
NSData *data1 = [object valueForKey:#"college_list"];
NSString *myString =[ NSString stringWithCString:[data1 bytes] encoding:NSUTF8StringEncoding];
What is wrong with this code?
If 'data1' do have some thing in it. Try this:
[[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding]
May be there is some this wrong with your 'object'. Check its data is valid or issue is in its data.

AVAudioPlayer stops

I'm trying to play a mp3 file with using AVAudioPlayer:
NSString *path = NSString stringWithFormat:#"%#/%#" ,
[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSURL* url = [NSURL fileURLWithPath:path];
AVAudioPlayer* player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
[player play];
NSLog(#"%f/%f", player.currentTime, player.duration);
However, the player stops around 478.558367 every time even though its duration is 1044.437506.
Why does the player stop in the middle of the track?

NSURLResponse Content-Length mismatch size of actual data when running concurrent downloads

I have a UITableView, when a cell is selected, I make a service call to asynchronously download a PDF file from a web service. It works great, until you select multiple cells directly after one-another (individually), then things start going south..
Here's some (stripped down) code to clarify:
Inside MasterViewController.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//To uniquely identify this field, I build a simple string using the indexPath.
NSString *key = [[NSString alloc]initWithFormat:#"%d.%d",pIndex.section,pIndex.row];
//Use a pre-populated NSDictionary to specify the file I want from the server.
NSString *reportID = [reportDictionary valueForKey:key];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/RequestReportWithID",myConnectionObject.ServiceURL]];
NSMutableDictionary *body = [[NSMutableDictionary alloc] initWithObjectsAndKeys:reportID, #"reportID", nil];
NSData *requestData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: requestData];
//Create a new object as delegate to receive the data, also add the key to assist with identification.
ReportDownloader *newReportDownloader = [[ReportDownloader alloc]initWithDelegate:self andKey:key];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:newReportDownloader];
if (connection)
{
//Nothing to do here, request was made.
}
}
Inside ReportDownloader.m:
long long expectedReportSize;
NSString *key;
NSData *thisReport;
-(NSObject*)initWithDelegate:(NSObject*)pDelegate andKey:(NSString*)pKey
{
myTypedDelegate = (MasterViewController*)pDelegate;
Key = pKey;
return self;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
expectedReportSize = [response expectedContentLength];
NSLog(#"Key:%#, Expected Size=%lld bytes",Key, [response expectedContentLength]);
thisReport = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[thisReport appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//Here is where things go wrong...
NSLog(#"Key:%#, Actual Size=%ld bytes",Key, (unsigned long)[thisReport length]);
}
The above code works fine for a single report. And on a fast line, it works fine for 3-4 reports, but try to do more than that and the Expected length starts mismatching the Actual length. And I can't understand whyyyyy....
See the output generated by the code above:
(Notice that only the report for indexPath 1.1 was downloaded correctly)
Key:1.0, Expected Size=304006 bytes
Key:1.3, Expected Size=124922 bytes
Key:1.0, Actual Size=369494 bytes
Key:1.3, Actual Size=380030 bytes
Key:1.2, Expected Size=179840 bytes
Key:1.4, Expected Size=377046 bytes
Key:1.2, Actual Size=114376 bytes
Key:1.5, Expected Size=175633 bytes
Key:1.4, Actual Size=180558 bytes
Key:1.5, Actual Size=274549 bytes
Key:1.1, Expected Size=443135 bytes
Key:1.1, Actual Size=443135 bytes
The data corruption is confirmed when trying to open the PDF documents, which fail for all file's who's data size didn't match the expectedContentLength.
I am completely baffled by this behaviour, I'm hoping that I'm making an obvious n00b mistake and that someone here spots it.
The main reason WHY I made the ReportDownloader class was to avoid problems like this one.
Thanks in advance to whoever takes the time to scan my code!
Ok, the solution to this problem can be found here:
https://stackoverflow.com/a/1938395/1014983
This answer by James Wald, although not the question's accepted answer, completely solved all my problems with multiple simultaneous async NSURLConnections.
Let me know if you need some help with the implementation, but it's pretty straight forward.

Receiving Corrupted Info From Server

On Iphone as well as android I am getting response codes of 200 meaning that I am getting a valid and good response with no errors, but the json that I am receiving has additional characters. I print out the NSData that I receive and it is 580 in length and the NSString, at least when it fails, will have a larger length and print n+ extra characters on the end of the json. I am not sure why this would be but thought I would see if anyone can see what I would be doing incorrectly.
NSString *post = [NSString stringWithFormat:#"referer=%#&username=%#&password=%#", referer, username, password];
NSData *pData = [post dataUsingEncoding: NSUTF8StringEncoding allowLossyConversion:YES];
NSString *pLength = [NSString stringWithFormat:#"%d", [pData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:self.url];
[request setHTTPMethod:#"POST"];
[request setValue:pLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:pData];
[request setTimeoutInterval:30];
NSHTTPURLResponse *response = nil;
NSError *err = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *sData = [NSString stringWithUTF8String:[data bytes]];
I do not receive any errors and every response code that I receive is 200. I have printed out all of these values as well. data length is 580 and sData will vary at times but when it does pass it will be 580 in length, but this can change for different cases. The data will not always be 580 for other users that use the system.
ANSWER:
I solved the problem instead of using
NSString *sData = [NSString stringWithUTF8String:[data bytes]];
You should use
NSString *sData = [[NSString alloc] initWithData: data encoding: NSUTF8String];
This will alloc the correct amount of space based on the NSData object and thus the NSString will never try to access or store more space in that may be behind the last address that should have been accessed.
ANSWER:
I solved the problem instead of using
NSString *sData = [NSString stringWithUTF8String:[data bytes]];
You should use
NSString *sData = [[NSString alloc] initWithData: data encoding: NSUTF8String];
This will alloc the correct amount of space based on the NSData object and thus the NSString will never try to access or store more space in that may be behind the last address that should have been accessed.

Problem with stringByTrimmingCharactersInSet:

I'm doing a very simple trimming from a string. Basically it goes like this:
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"%#",s);
[pool drain];
return 0;
}
No matter how many times I check, I can't find a mistake on the code. But the compiler keeps returning:
Running…
2009-12-30 08:49:22.086 Untitled[34904:a0f] Some other string
It doesn't trim the string at all. Is there a mistake in my code, because I can't believe something this simple doesn't work. Thanks!
Edit:
I think I've figured my mistake. stringByTrimmingCharactersInSet only trims the string from the leftmost and rightmost ends of a string. Can anybody confirm this?
You are correct - with your code stingByTrimmingCharactersInSet will trim the left and right whitespace but leave internal whitespace alone.
Note that there's also a memory leak in your code sample:
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
This will leak when you re-assign to s in the next line.

Resources