How can i make a random sound array with objective c? - objective-c

So i've done the tutorial where you code a button so that when you press it a sound plays. I'm trying to modify it so that when the button is pressed, a random sound plays.
here is the code:
viewcontroller.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#interface STViewController : UIViewController
- (IBAction)playAudio:(id)sender;
#property (nonatomic, strong) NSArray *sounds;
#end
viewcontroller.m
#import <AVFoundation/AVFoundation.h>
#import "STViewController.h"
#interface STViewController ()
#property (weak, nonatomic) IBOutlet UIButton *playAudio;
#end
#implementation STViewController
- (IBAction)playAudio:(id)sender {
AVAudioPlayer *audioPlayer;
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"Woof" ofType:#"mp3"];
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
NSError *audioError = [[NSError alloc] init];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&audioError];
if (!audioError) {
[audioPlayer play];
NSLog(#"Woof!");
}
else {
NSLog(#"Error!");
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I've been dabbling with something along these lines
- (NSArray *)sounds
{
NSArray *sounds = [NSArray arrayWithObjects:
#"Woof.mp3",
#"Meow.mp3",
#"tweet.mp3",
#"Squeak.mp3",
#"Moo.mp3",
#"Croak.mp3",
#"Toot.mp3",
#"Quack.mp3",
#"Blub.mp3",
#"OWOwOw.mp3",
#"Fox.mp3",
nil];
return sounds;
}
but i'm not really sure how to make it random or even implement in in the code that I have going right now. Anyone have any ideas?

Just make it random try below:-
NSMutableArray *array=[NSMutableArray
arrayWithObjects:
#"Woof.mp3",
#"Meow.mp3",
#"tweet.mp3",
#"Squeak.mp3",
#"Moo.mp3",
#"Croak.mp3",
#"Toot.mp3",
#"Quack.mp3",
#"Blub.mp3",
#"OWOwOw.mp3",
#"Fox.mp3",
nil];
// now use exchangeobject with index api
int i=0;
for(i=0;i<=[array count]; i++)
{
NSInteger rand=(arc4random() %10);
[array exchangeObjectAtIndex:i
withObjectAtIndex:rand];
}

Related

How to display CNContact using CNContactViewController on OSX

I am trying to display CNContact on the new CNContactViewController. I am getting no card selected. I tried this with unsaved contact (no go). Also tried with saved+fetched from CNContactStore also no go. Tried with "me" contact but the same result. According to the debugger fetched contact is loaded with correct values and is not nil/empty. App is sandboxed and correctly asks for Contacts permission.
Here is sample:
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
#import "AppDelegate.h"
#interface AppDelegate ()
#property (weak) IBOutlet NSWindow *window;
#property (strong) CNContact *contact;
#property (strong) CNContactViewController *controller;
#end
#implementation AppDelegate
- (instancetype)init {
self = [super init];
if (self) {
_controller = [[CNContactViewController alloc] init];
}
return self;
}
- (void)awakeFromNib
{
CNContactStore *store = [[CNContactStore alloc] init];
CNMutableContact *mutContact = [[CNMutableContact alloc] init];
NSString *identifier = [mutContact identifier];
mutContact.givenName = #"GivenName";
mutContact.familyName = #"FamilyName";
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
[saveRequest addContact:mutContact toContainerWithIdentifier:[store defaultContainerIdentifier]];
[store executeSaveRequest:saveRequest error:nil];
id keysToFetch = #[[CNContactViewController descriptorForRequiredKeys]];
_contact = [store unifiedContactWithIdentifier:identifier keysToFetch:keysToFetch error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
self.controller.contact = self.contact;
self.window.contentViewController = self.controller;
self.window.contentView = self.controller.view;
});
}
#end
EDIT: 6th of October 2015
Apple's TSI confirmed that they can't get it to work on OS X 10.11.0
The solution is to set the contact after loading the view.
TSI: Thank you for your patience while I was reaching out to the
Contacts engineers. Your issue is a bug whose workaround is to set the
contact after presenting the contact view controller.
#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
#import "ViewController.h"
#interface ViewController()
#property (strong) CNContactStore *store;
#property (strong) CNContactViewController *controller;
#property(nonatomic, copy) NSString *contactIdentifier;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.store = [[CNContactStore alloc] init];
[self saveContact];
}
-(void)saveContact
{
CNMutableContact *mutContact = [[CNMutableContact alloc] init];
mutContact.givenName = #"GivenName";
mutContact.familyName = #"FamilyName";
CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
[saveRequest addContact:mutContact toContainerWithIdentifier:[self.store defaultContainerIdentifier]];
[self.store executeSaveRequest:saveRequest error:nil];
self.contactIdentifier = [mutContact identifier];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
- (IBAction)displayContact:(id)sender {
id keysToFetch = #[[CNContactViewController descriptorForRequiredKeys]];
CNContact *contact = [self.store unifiedContactWithIdentifier:self.contactIdentifier keysToFetch:keysToFetch error:nil];
self.controller = [[CNContactViewController alloc] init];
[self.controller.view setFrameSize:NSMakeSize(500, 500)];
[self presentViewController:self.controller asPopoverRelativeToRect:self.view.bounds ofView: self.view preferredEdge: NSMaxXEdge behavior:NSPopoverBehaviorTransient];
self.controller.contact = contact;
}

How do i play many sounds selected by picker?

I want to make an app playing sound selected by picker.
When i select a file by picker, if i touch button, the sound will play.
But, it cannot.
I cannot point the miss of the code.
Anyone can help me to troubleshoot my code?
Here is my code for troubleshooting.
.H file
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController : UIViewController <
UIPickerViewDelegate,UIPickerViewDataSource,AVAudioPlayerDelegate> {
NSArray *ap;
NSString *si;
UIButton * utab;
AVAudioPlayer *apr;
}
#property (weak, nonatomic) IBOutlet UILabel *ll;
#property (weak, nonatomic) IBOutlet UIImageView *igv;
#property (weak, nonatomic) IBOutlet UIPickerView *pv;
#property (weak, nonatomic) NSArray *msa;
#end
.M file
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property AVAudioPlayer *apr;
#end
#implementation ViewController
#synthesize ll,igv,pv;
- (void)viewDidLoad
{
[pv setDelegate:self];
[pv setDataSource:self];
[ll setText:[ap objectAtIndex:0]];
ap = [NSArray arrayWithObjects:#"AAA",#"BBB",#"CCC",#"DDD",#"EEE", nil];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#.m4a",[[NSBundle mainBundle] resourcePath]]];
NSError *error;
self.apr = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
apr.numberOfLoops = 2;
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [ap count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent: (NSInteger)component {
return [ap objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component {
si = [ap objectAtIndex:row];
[ll setText:si];
NSString *in = [NSString stringWithFormat:#"%#.jpg",si];
UIImage *tig = [UIImage imageNamed:in ];
[igv setImage:tig];
}
- (IBAction)utabu {
[self.apr play];
}
#end
Most likely the sound file could not be loaded. You should check the error variable after initializing the AVAudioPlayer.
The code for creating the URL objects is also wrong. You should use:
[[NSBundle mainBundle] URLForRessource:<filename> withExtension:"m4a"]
Also you would have to create a new AudioPlayer each time a sound file is selected.
Next time please use better variable names and not just two or three letter garbage.

Parsing JSON with AFHTTPClient

I'm using the AFNetworking library to parse json using the AFHTTPClient. I can verify that the json is being parsed within the client block and send that data to my json model. However, when I try to access the json model from outside the block I get no data. How can I pass the parsed json data to the json model then access that model data elsewhere in the app?
the AFHTTPClient subclass / singleton:
#import <Foundation/Foundation.h>
#import "AFHTTPClient.h"
#interface JsonClient : AFHTTPClient
+ (JsonClient *)sharedClient;
#end
#import "JsonClient.h"
#import "AFJSONRequestOperation.h"
static NSString *const kJsonBaseURLString = #"https://alpha-api.app.net/";
#implementation JsonClient
+ (JsonClient *)sharedClient {
static JsonClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[JsonClient alloc] initWithBaseURL:[NSURL URLWithString:kJsonBaseURLString]];
});
return _sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setDefaultHeader:#"Accept" value:#"application/json"];
return self;
}
#end
the JSON model data:
#import <Foundation/Foundation.h>
#interface TheJson : NSObject
#property (nonatomic, copy) NSString *createdAt;
#property (nonatomic, copy) NSString *userText;
- (id)initWithDictionary:(NSDictionary *)dict;
#end
#import "TheJson.h"
#implementation TheJson
- (id)initWithDictionary:(NSDictionary *)dict {
self = [super init];
if (self) {
self.createdAt = [dict objectForKey:#"created_at"];
self.userText = [dict objectForKey:#"text"];
}
return self;
}
#end
the ViewController to update the user interface:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#end
#import "ViewController.h"
#import "JsonClient.h"
#import "TheJson.h"
#interface ViewController ()
#property (weak) IBOutlet UILabel *createdLabel;
#property (weak) IBOutlet UILabel *textLabel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)fetchJsonData:(id)sender {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[[JsonClient sharedClient] getPath:#"stream/0/posts/stream/global" parameters:nil
success:^(AFHTTPRequestOperation *operation, id JSON) {
NSArray *postsFromResponse = [JSON valueForKeyPath:#"data"];
NSDictionary *dictFromArray = postsFromResponse[0];
TheJson *jsonObject = [[TheJson alloc] initWithDictionary:dictFromArray];
NSLog(#"createdAt is %#", jsonObject.createdAt);
NSLog(#"text from user is %#", jsonObject.userText);
[self updateInterface];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error is %#", [error description]);
}
];
}
- (void)updateInterface {
TheJson *thejson;
[_createdLabel setText:thejson.createdAt];
[_textLabel setText:thejson.userText];
}
#end
You haven't passed the new jsonObject out of the block nor stored it anywhere. A short term answer is to declare updateInterface to take the jsonObject as a parameter.
So your updateInterface becomes updateInterface: something like this:
- (void)updateInterface:(TheJson*)thejson {
[_createdLabel setText:thejson.createdAt];
[_textLabel setText:thejson.userText];
}
...and then within your block, you call this method like this:
[self updateInterface:jsonObject];
Longer term, if your app has many of these objects and/or needs to hold onto them for any amount of time, you probably want to think about how you will store and organize these as you download them.

Saving the title of a button so it can be accessed in another view (Objective-C)

I'm trying to save the name of a button using a singleton so that the name can be accessed in another view to play a video with the same name. However, I'm getting the error: SIGABRT. I don't really see what's wrong with my code. Any ideas?
#import "List.h"
#import "MyManager.h"
#import "Video.h"
#implementation ExerciseList
-(IBAction) goToVideo:(UIButton *) sender{
MyManager *sharedManager = [MyManager sharedManager];
sharedManager.vidName = [[sender titleLabel] text];
Video *videoGo = [[Video alloc] initWithNibName: #"Video" bundle: nil];
[self.navigationController pushViewController: videoGo animated: YES];
[videoGo release];
}
Here is my .h and .m for MyManager:
#import <foundation/Foundation.h>
#interface MyManager : NSObject {
NSMutableArray *workouts;
NSString *vidName;
}
#property (nonatomic, retain) NSMutableArray *workouts;
#property (nonatomic, retain) NSString *vidName;
+ (id)sharedManager;
#end
#import "MyManager.h"
static MyManager *sharedMyManager = nil;
#implementation MyManager
#synthesize workouts;
#synthesize vidName;
#pragma mark Singleton Methods
+ (id)sharedManager {
#synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}
- (id)init {
if ((self = [super init])) {
workouts = [[NSMutableArray alloc] init];
vidName = [[NSString alloc] init];
}
return self;
}
-(void) dealloc{
self.workouts = nil;
self.vidName = nil;
[super dealloc];
}
#end
You should access the title of the button
sharedManger.vidName = [sender currentTitle];
However you are not using ARC so also check where your vidName property is retain or copy.
if it is not retain or copy then you can use this code also
if(sharedManger.vidname != nil){
[sharedManger.vidName release];
sharedManger.vidName = nil;
}
sharedManger.vidName = [[sender currentTitle] retain];

EXC_BAD_ACCESS when I change moviePlayer contentURL

In few words, my application is doing that :
1) My main view (RootViewController) has a buton when I tap on it, it displays the player (PlayerViewController) :
2) In my Player, I initialize the video I want to play
-> It's working good, my movie is display
My problem :
When I go back to my main view :
And I tap again on the button, I get a *Program received signal: “EXC_BAD_ACCESS”.*
If I comment self.player.contentURL = [self movieURL]; it's working, but when I let it, iI have this problem.
I read that it's due to null pointer or memory problem but I don't understand why it's working the first time and not the second time. I release my object in dealloc method.
Thanks for your help !
Bruno.
Here is my code :
Root View Controller
RootViewController.h
#import <UIKit/UIKit.h>
#import "PlayerViewController.h"
#interface RootViewController : UIViewController {
IBOutlet UIButton * myButton;
}
#property (nonatomic,retain) IBOutlet UIButton * myButton;
-(IBAction)displayPlayer:(id)sender;
- (void) returnToRoot: (PlayerViewController *) controller;
#end
RootViewController.m
#import "RootViewController.h"
#implementation RootViewController
#synthesize myButton;
-(IBAction)displayPlayer:(id)sender
{
PlayerViewController *playerViewController = [[PlayerViewController alloc] initWithNibName:#"PlayerViewController" bundle:nil];
playerViewController.delegate = self;
playerViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController: playerViewController animated: YES];
[playerViewController release];
}
- (void) returnToRoot: (PlayerViewController *) controller
{
[self dismissModalViewControllerAnimated: YES];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
#end
Player View Controller
PlayerViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MPMoviePlayerController.h>
#protocol PlayerViewControllerDelegate;
#interface PlayerViewController : UIViewController {
UIView *viewForMovie;
MPMoviePlayerController *player;
}
#property (nonatomic, assign) id <PlayerViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIView *viewForMovie;
#property (nonatomic, retain) MPMoviePlayerController *player;
- (NSURL *)movieURL;
-(IBAction)goBackToRoot:(id)sender;
#end
#protocol PlayerViewControllerDelegate
- (void) returnToRoot: (PlayerViewController *) controller;
#end
PlayerViewController.m
#import "PlayerViewController.h"
#implementation PlayerViewController
#synthesize player;
#synthesize viewForMovie;
#synthesize delegate;
- (void)dealloc {
[super dealloc];
[player release];
[viewForMovie release];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"viewDidLoad");
self.player = [[MPMoviePlayerController alloc] init];
[self.player autorelease];
self.player.view.frame = self.viewForMovie.bounds;
self.player.view.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[self.viewForMovie addSubview:player.view];
self.player.contentURL = [self movieURL];
[self.player play];
}
-(NSURL *)movieURL
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath =
[bundle
pathForResource:#"myVideo"
ofType:#"mp4"];
if (moviePath) {
return [NSURL fileURLWithPath:moviePath];
} else {
return nil;
}
}
-(IBAction)goBackToRoot:(id)sender{
[self.delegate returnToRoot: self];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
#end
Problem
The second time I call "displayPlayer" I had the EXC_BAD_ACCESS
I solved it !!!
I look on the MPMoviePlayerController to see what kind of variable is contentURL
(NSURL *)contentURL
It means I have also to liberate it.
I do that in my dealloc method putting a nil value:
-(void) dealloc {
[super dealloc];
self.player.contentURL = nil;
[player release];
[viewForMovie release];
}
If I comment self.player.contentURL =
[self movieURL]; it's working, but
when I let it, iI have this problem.
In that case, how is contentURL declared? Does the #property definition include copy or retain?