pointer loop to integer conversion? - objective-c

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.

Related

Still confused by Objective C variable scope

I am trying to get some employee data from a JSON service. I am able to get the data and load it into an NSMutableArray, but I cannot access that array outside the scope of the method that gets the data.
TableViewController h filed
#import <UIKit/UIKit.h>
#import "employee.h"
#interface ViewController : UITableViewController
{
//NSString *test;
//NSMutableArray *employees;
}
#end
And here is my m file:
#define kBgQueue dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define scoularDirectoryURL [NSURL URLWithString: #"https://xxxx"]
#import "ViewController.h"
#interface ViewController()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
scoularDirectoryURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSMutableArray *jsonArray = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &error];
id jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSMutableArray *employees = [[NSMutableArray alloc ]init];
if (!jsonArray) {
} else {
for (jsonObject in jsonArray){
employee *thisEmployee = [employee new];
thisEmployee.fullName = [jsonObject objectForKey:#"$13"];
thisEmployee.state = [jsonObject objectForKey:#"state"];
thisEmployee.city = [jsonObject objectForKey:#"city"];
[employees addObject:thisEmployee];
}
}
}
Any help would be appreciated.
Bryan
You were on the right track. All you have to do is uncomment the NSMutableArray declaration in your #interface, and then change this line:
NSMutableArray *employees = [[NSMutableArray alloc] init];
to this
employees = [[NSMutableArray alloc] init];
Declaring the array in your interface will allow it to be accessed from anywhere within your implementation, or even from other classes and files if you declare it as a public property. When you make a declaration inside a function, that variables scope does not extend to outside of the function.
Just to elaborate a little on the scope of the variables, you have several ways of declaring them. The most used are:
Instance variables, which are declared in your interface and they can be accessed from any method inside the class or inside any method from it's subclasses. For example:
#interface MyObject : NSObject { //this can be any class
NSString *instanceVariable;
}
#implementation MyObject
-(void)someStrangeMethod {
instanceVariable = #"I'm used here";
NSLog(#"%#",instanceVariable);
}
//from subclasses
#interface MySubclassObject: MyObject {
//see that the variable is not declared here;
}
#implementation MySubclassObject
-(void)anotherStrangeMethod {
[super someStrangeMethod]; // this will print the value "I'm used here"
instanceVariable = #"I'm changing my value here"; //here we access the variable;
}
If you want the instance variable to be accessed only from the "owner" class you can declare it after the #private tag. You also have the #protected tag, though that isn't used so much.
If you want to have a variable that can be accessed outside the class, declare it as a property in your interface.
Also you can make the properties private using #private but this will contradict the purpose of the properties.

IOS can I use AVAudioPlayer on the appDelegate?

I have a TabBarController with two tabs and I want to play music on both tabs. Right now I have my code on the main appDelegate
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"My Song"
ofType:#"m4a"]]; // My Song.m4a
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
//audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
}
but I'm getting the error Program received signal: "SIGABRT" on UIApplicationMain
Is there a better way to accomplish what I'm trying to do? If this is how I should do it, where do I start checking for problems?
yes you can use AVAudioPlayer in App Delegate.
What you need to do is:-
In appDelegate.h file do:-
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
AVAudioPlayer *_backgroundMusicPlayer;
BOOL _backgroundMusicPlaying;
BOOL _backgroundMusicInterrupted;
UInt32 _otherMusicIsPlaying;
Make backgroundMusicPlayer property and sythesize it.
In appDelegate.m file do:-
Add these lines in did FinishLaunching method
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
// Create audio player with background music
NSString *backgroundMusicPath = [[NSBundle mainBundle] pathForResource:#"SplashScreen" ofType:#"wav"];
NSURL *backgroundMusicURL = [NSURL fileURLWithPath:backgroundMusicPath];
NSError *error;
_backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error];
[_backgroundMusicPlayer setDelegate:self]; // We need this so we can restart after interruptions
[_backgroundMusicPlayer setNumberOfLoops:-1]; // Negative number means loop forever
Now implement delegate methods
#pragma mark -
#pragma mark AVAudioPlayer delegate methods
- (void) audioPlayerBeginInterruption: (AVAudioPlayer *) player {
_backgroundMusicInterrupted = YES;
_backgroundMusicPlaying = NO;
}
- (void) audioPlayerEndInterruption: (AVAudioPlayer *) player {
if (_backgroundMusicInterrupted) {
[self tryPlayMusic];
_backgroundMusicInterrupted = NO;
}
}
- (void)tryPlayMusic {
// Check to see if iPod music is already playing
UInt32 propertySize = sizeof(_otherMusicIsPlaying);
AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &_otherMusicIsPlaying);
// Play the music if no other music is playing and we aren't playing already
if (_otherMusicIsPlaying != 1 && !_backgroundMusicPlaying) {
[_backgroundMusicPlayer prepareToPlay];
if (soundsEnabled==YES) {
[_backgroundMusicPlayer play];
_backgroundMusicPlaying = YES;
}
}
}

AVAudioPlayer is leaking, where should i release it??

i m trying to play background.mp3 files as my game playback file ,and it works fine
but it leaking memory
#interface slots2ViewController : UIViewController <AVAudioPlayerDelegate>
{
AVAudioPlayer *PlayBack;
}
#property(nonatomic, retain) AVAudioPlayer *PlayBack ;
.m file
#synthesize PlayBack;
-(void)LoadnPlaySound
{
NSString *SubDir = [NSString stringWithFormat:#"AudioFiles/Theme%d",SlotId];
NSURL* file_url2 = nil;
file_url2 = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"background"ofType:#"mp3" inDirectory:SubDir ]];
AVAudioPlayer* TmpPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:file_url2 error:nil];
self.PlayBack = TmpPlayer;
self.PlayBack.delegate = self;
[TmpPlayer release];
[self.PlayBack prepareToPlay];
[self.PlayBack play];
[release file_url2];
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)ThePlayer successfully:(BOOL)flag
{
[self.PlayBack play];
}
memory leak instrument says [self.PlayBack prepareToPlay] is the point of 100% leak
i m calling LoadnPlaySound whenever i m changing the theme.
also do i need to release self.PlayBack if yes then where

ASINetworkQueue requests always fails - ios

I'm facing a little bit of trouble finding whats wrong with my code, because I'm trying to download several images from different urls and the requests are always failing.
Could you guys give me a little help?
Here is my code:
//
// Chapters.h
//
//
// Created by Nuno Martins on 11/07/18.
// Copyright 2011 WeTouch. All rights reserved.
//
#import <Foundation/Foundation.h>
//#import <GHUnit/GHUnit.h>
#class ASINetworkQueue;
#interface Chapters : NSObject {
NSString * chaptersBaseUrl;
NSMutableArray * chaptersList;
ASINetworkQueue *networkQueue;
}
#property (retain) ASINetworkQueue *networkQueue;
#property (nonatomic, retain) NSString *chaptersBaseUrl;
#property (nonatomic, retain) NSMutableArray *chaptersList;
-(void)downloadChaptersIconsFromUrlArrayToFile:(NSMutableArray *)iconUrls;
#end
//
// Chapters.m
//
//
// Created by Nuno Martins on 11/07/18.
// Copyright 2011 WeTouch. All rights reserved.
//
#import "Chapters.h"
#import "Chapter.h"
#import "PDFDataAgregator.h"
#import "ASIHTTPRequest.h"
#import "ASINetworkQueue.h"
#implementation Chapters
#synthesize chaptersBaseUrl;
#synthesize chaptersList;
#synthesize networkQueue;
- (void)dealloc
{
[networkQueue release];
[super dealloc];
}
-(void)downloadChaptersIconsFromUrlArrayToFile:(NSMutableArray *)iconUrls
{
networkQueue = [[ASINetworkQueue alloc] init];
// Stop anything already in the queue before removing it
[networkQueue cancelAllOperations];
// Creating a new queue each time we use it means we don't have to worry about clearing delegates or resetting progress tracking
[networkQueue setDelegate:self];
[networkQueue setRequestDidFinishSelector:#selector(requestFinished:)];
[networkQueue setRequestDidFailSelector:#selector(requestFailed:)];
[networkQueue setQueueDidFinishSelector:#selector(queueFinished:)];
NSLog(#"Array-> %d", [iconUrls count]);
NSMutableArray *myIcons = [[NSMutableArray alloc] initWithArray:iconUrls];
//Create Chapters Folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *docDirectory = [paths objectAtIndex:0];
NSString *newDir = [docDirectory stringByAppendingPathComponent:#"Chapters"];
[[NSFileManager defaultManager] createDirectoryAtPath:newDir withIntermediateDirectories:YES attributes:nil error: NULL];
for(unsigned i = 0; i < [myIcons count]; i++)
{
NSURL *url = [NSURL URLWithString:[myIcons objectAtIndex:i]];
NSString *fileName = [url lastPathComponent];
NSString *filePath = [newDir stringByAppendingPathComponent:fileName];
NSLog(#"Icon File Path: %#",filePath);
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[iconUrls objectAtIndex:i]]];
[request setDownloadDestinationPath:filePath];
//[request setUserInfo:[NSDictionary dictionaryWithObject:#"request1" forKey:#"name"]];
[request setTemporaryFileDownloadPath:[filePath stringByAppendingPathExtension:#"download"]];
[request setAllowResumeForFileDownloads:YES];
[networkQueue addOperation:request];
}
[networkQueue go];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// You could release the queue here if you wanted
if ([networkQueue requestsCount] == 0) {
// Since this is a retained property, setting it to nil will release it
// This is the safest way to handle releasing things - most of the time you only ever need to release in your accessors
// And if you an Objective-C 2.0 property for the queue (as in this example) the accessor is generated automatically for you
[self setNetworkQueue:nil];
}
//... Handle success
NSLog(#"Request finished");
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
// You could release the queue here if you wanted
NSLog(#"Number of requests in Queue %d", [networkQueue requestsCount]);
if ([networkQueue requestsCount] == 0) {
[self setNetworkQueue:nil];
}
//... Handle failure
NSLog(#"Request failed");
}
- (void)queueFinished:(ASINetworkQueue *)queue
{
// You could release the queue here if you wanted
if ([networkQueue requestsCount] == 0) {
[self setNetworkQueue:nil];
}
NSLog(#"Queue finished");
}
Well this was a problem related with Bad url format.
I was passing http:/somesite.com/someimage.png instead of passing http://somesite.com/someimage.png
I was missing the / because when I append a BaseUrl string to the filename using stringByAppending path Component it removes one slash of the HTTP://.
Solved now!

AVAudioPlayer isPlaying crashing app

I'm using an AVAudioPlayer to manage some sounds but the isPlaying method seems to be crashing.
done when I initiate the page:
self.soundClass = [AVAudioPlayer alloc];
how I play the sound:
-(void)playSound:(NSString *)fileName:(NSString *)fileExt {
if ( [self.soundClass isPlaying] ){
[self.soundClass pause];
}
else if (newSoundFile == currentSoundFile) {
[self.soundClass play];
}
else {
NSLog(#"PlaySound with two variable passed function");
[[NSBundle mainBundle] pathForResource: fileName ofType:fileExt]], &systemSoundID);
[self.soundClass initWithContentsOfURL:[NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource: fileName ofType:fileExt]] error:nil];
[self.soundClass prepareToPlay];
[self.soundClass play];
}
self.currentSoundFile = fileName;
}
My soundClass is pretty empty right now:
soundclass.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import<AVFoundation/AVFoundation.h>
#interface SoundClass : AVAudioPlayer <AVAudioPlayerDelegate> {
}
#end
SoundClass.m
#import "SoundClass.h"
#implementation SoundClass
-(void)dealloc {
[super dealloc];
}
#end
Do you see anything here I might be doing wrong? It crashes right at if ( isPlaying )
You point to space that is allocated for an instance of AVAudioPlayer in the first line you list, but you don't actually initialize an instance. In Cocoa, "alloc" is 99.9% of the time followed by some form of -init (like -initWithContentsOfURL:error: in the case of AVAudioPlayer).
Also, "soundClass" is an odd name for an instance variable. You should read up on the difference between a class (the blueprint of an object) and an instance of a class (an actual object built from the blueprint). Solid knowledge of this concept is critical to your understanding of Cocoa (and all object-oriented) programming.