Create and call a function on a class? - objective-c

Hello good people of Stackoverflow, i'm trying to make a function that gets a number of seconds and then create a local alert, here is what i have:
I created a class named manualtimer.h this is a Nsobject class.
In the manualTimer.h i have the following code:
-(void)tempoAlerta:(NSTimeInterval *)otempo;
In the manualTimer.M i have the following code:
-(void)tempoAlerta:(NSTimeInterval *)otempo {
UIApplication* myapp = [UIApplication sharedApplication];
UILocalNotification* localnote = [[UILocalNotification alloc]init];
localnote.fireDate = [NSDate dateWithTimeIntervalSinceNow:*otempo];
localnote.alertBody = #"Nice Alert";
localnote.timeZone = [NSTimeZone defaultTimeZone];
NSMutableArray *notifications = [[NSMutableArray alloc] init];
[notifications addObject:localnote];
myapp.scheduledLocalNotifications = notifications;
}
In my viewcontroller, i imported the manualTimer.h, but for some reason a cannot call the function tempoAlerta()
any ideas? xCode show no errors?

you must to instantiate a object of that class
manualTimer *obj = [[manualTimer alloc] init];
and then call that function
[obj tempoalerta:otempo];

What you have in your example code is defining a Method not a function. Functions are c style void anExampleFunction(int anArgument) and cannot be defined on objective-c classes.
How are you calling the method?
Your call should look something like this:
ManualTimer *timer = [ManualTimer new];
[timer temoAlerta:10];
Please look at this documentation for more information:
https://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/#//apple_ref/doc/uid/TP40007594-CH1-SW11

Related

Open ears text to speech (voice) not working when getting string from another class/controller (IOS, Objective c)

I am very new to objective c and OpenEars so please forgive me if I have some messy code and if I am lost in very simple problem.
Anyhow, I have two controllers in this application. The first being the default ViewController and the second one being a new one that I made called ReplyManagerController.
The code in the ViewController basically uses the one in the tutorial with some (maybe more some) changes.
EDIT:
The app is supposed to be a basic app where a user says something and the app replies.
But the original problem was that I could not get the string to display or TTS to work when my ViewController got it's string from another class/controller.
The answer in my below mentions that it was probably because my other class was calling my ViewController without the self.fliteController initialized.
How would I initialize the ViewController with self.fliteController initialized?
ViewController.m
- (void) pocketsphinxDidReceiveHypothesis:(NSString *)hypothesis recognitionScore:(NSString *)recognitionScore utteranceID:(NSString *)utteranceID {
NSString *strResult = hypothesis; //speech to text to string
ReplyManager* replyObject = [[ReplyManager alloc] init];
[replyObject speechResult:(NSString*)strResult viewController:self];
}
- (void) getReply:(NSString*)replyStr{
[self.fliteController say:replyStr withVoice:self.slt];
[self updateText:replyStr];
}
- (IBAction)updateText:(NSString*)replyStr{
labelOne.text = replyStr;
labelOne.adjustsFontSizeToFitWidth = YES;
labelOne.minimumFontSize = 0;
}
Any help will be great! Thanks!
ReplyManager.m
- (void) speechResult:(NSString*)strResult {
NSString *replystr;
NSString *greetings = #"Hi!";
NSString *sorry = #"Sorry I didn't catch that?";
ViewController* getReply = [[ViewController alloc] init];
if ([strResult isEqualToString:#"HELLO"])
{
replystr = greetings;
[getReply getReply:(NSString*)replystr];
}
else
{
replystr = sorry;
[getReply getReply:(NSString*)replystr];
}
}
EDIT 2:
viewDidLoad Method
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.fliteController = [[OEFliteController alloc] init];
self.slt = [[Slt alloc] init];
self.openEarsEventsObserver = [[OEEventsObserver alloc] init];
[self.openEarsEventsObserver setDelegate:self];
}
ViewController* getReply = [[ViewController alloc] init];
Here you init a new ViewController which does not have self.fliteController defined most likely. You need to reuse previos controller, for example like this:
[replyObject speechResult:(NSString*)strResult viewController:self];
So you can use already initialized viewController later. Overall it is better to initialize objects like viewController or replyController beforehand, not inside callback methods.
It sounds like a timing issue where you're trying to use fliteController before it's been initialized.
In your ViewController class, where do you assign a value to the fliteController property? In an initializer? -(void)viewDidLoad?
In ReplyManagerController add:
ViewController* getReply = [[ViewController alloc] init];
// Add these lines
NSLog(getReply.fliteController); // Is this nil?
[getReply.view layoutIfNeeded];
NSLog(getReply.fliteController); // Is it still nil?
Does the above fix the problem? If so, you're probably initializing fliteController in -(void)viewDidLoad. What's the result of the two NSLog statements?

Handling CLLocationManager delegate from another class

I have 2 classes as NSObject subclasses:
1st class is more likely act as adapter. It send data to Class2 for process async task. When delegaton fired I would like to post back data to adaptor class.
In adaptor class:
Class2 *cls = [[Class2 alloc] init];
[ftc fetchLocation];
In Class2.m
-(void)fetchLocation{
if(IS_OS_8_OR_LATER) {
[self.locationManager requestAlwaysAuthorization];
}
self.locationManager = [[CLLocationManager alloc] init];
if ([CLLocationManager locationServicesEnabled]){
NSLog(#"Enable");
}
self.locationManager.delegate =self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
[self.locationManager startUpdatingLocation];
}
When I call fetch-location method from adaptor, it really calls and reads lines, but after that, Class2 disappears and gone back to Adapter class without waiting delegation (didUpdateLocations)
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSString *latitude = [NSString stringWithFormat:#"%f",self.locationManager.location.coordinate.latitude];
NSString *longtitude = [NSString stringWithFormat:#"%f",self.locationManager.location.coordinate.longitude];
NSString *altitude = [NSString stringWithFormat:#"%f",self.locationManager.location.altitude];
NSString *speed = [NSString stringWithFormat:#"%f",self.locationManager.location.speed];
NSDictionary *locationDictionary = #{#"latitude":latitude,#"longtitude":longtitude,#"altitude":altitude,#"speed":speed};
if (locations.count >0 && [locations isKindOfClass:[NSArray class]]) {
[self.delegate userLocationHasUpdated:self :locationDictionary];
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
return;
}
}
But if I just run Class2 and remove adapter from compile (with first initialiser) it runs as expected, How can I achieve to handle delegation methods from another class that fired ?
Best Regards.
You have several options, really. One could be making your second class a property of your first class (singleton pattern would fit nice here, I guess). Then you can either declare a protocol in your second class and notify your first class via delegate methods (non-singleton implementation) or use NSNotificationCenter to post a notification (singleton implementation).
The second option would be to pass a block with completion handler to the second class. You could declare your method in the second class like this, for example (adjust return type and arguments of the block, if needed):
- (void)updateLocationWithCompletionHandler:(void (^)(void))completion;
Implement it so that you call the completion block after you get the geolocation update results.
And call it from the first class like:
[self.secondClass updateLocationWithCompletionHandler:^
{
// Your completion code here.
}];
Hope this helps (sorry, didn't check the code in Xcode, get rid of typos, if any).
Possible duplicate of iOS CLLocationManager in a separate class. You have to create a singleton class for to get the location if you want to have seperate class for handing the location manager. You will find the guidance from the shared link

AVSpeechSynthesizer delegate method didStartSpeechUtterance not being called

I am having trouble wth AVSpeechSynthesizer and utterances (ios 7.1.1)
The AVSpeechSynthesizer is initialised in a handler class with the delegate as self:
self.synthesizer = [[AVSpeechSynthesizer alloc] init];
self.synthesizer.delegate = self;
I have the following methods implemented in the delegate:
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance {
NSLog(#"Finish");
}
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance{
NSLog(#"Start");
}
and my speech is called via this method:
- (void)speak:(NSString *)spokenWord{
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:spokenWord];
[self.synthesizer speakUtterance:utterance];
}
I then call the method repeatedly e.g.
[AVhandler speak:_word];
[AVhandler speak:_word];
[AVhandler speak:_word];
I would expect to see in the log:
Start
Finish
Start
Finish
Start
Finish etc
But instead I see:
Start
Finish
Finish
Finish
Finish
Why is the didStartSpeechUtterance not being called?
Thanks.
Answer is a little late, apologies. To resolve this, also put:
synthesizer.delegate = self;
in the -(void) as below
- (void)speak:(NSString *)spokenWord{
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:spokenWord];
[self.synthesizer speakUtterance:utterance];
synthesizer.delegate = self;
}
and in the didFinish as below:
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance {
NSLog(#"Finish");
synthesizer.delegate = self;
}
Also don't forget to add a reference to the AVSpeechSynthesizerDelegate Protocol in your .h file, such as:
#interface ViewController : UIViewController <AVSpeechSynthesizerDelegate>
Then you can put your synthesizer.delegate = self; in your ViewDidLoad method only.
Hope it helps.

Incorrect decrement of reference count in analyzer [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I use NSTimer
Decrement Issue
I'm really struggling to get rid of the following warning:
Incorrect decrement of the reference count of an object that is at this point not owned by the caller.
The code compiles fine and the app seems to work fine. Basically I am trying to create an object of a class to play a short audio clip when the button is pressed. I've created a class to play the file and the objects are passed the files name as a string.
Here is the code:
- (IBAction) playKick
{
PlayAudio *thisPlayAudio= [[[PlayAudio alloc] init] playFile:(#"RockSnare")];
[thisPlayAudio release];
}
I've read the other posts and any help would be much appreciated!
I'd have to see the class definition for PlayAudio, but it's doubtful the playFile method returns its PlayAudio instance. You probably want this:
PlayAudio *thisPlayAudio = [[PlayAudio alloc] init];
[thisPlayAudio playFile:(#"RockSnare")];
[thisPlayAudio release];
Maybe this would help:
- (IBAction) playKick {
PlayAudio *thisPlayAudio= [[PlayAudio alloc] init];
[thisPlayAudio playFile:(#"RockSnare")];
[thisPlayAudio release];
}
This finishes creating the object and assigns it to thisPlayAudio, then plays the audio. What you have sets thisPlayAudio to the result of the playFile call.
What is the return type of the playFile: method? Are you sure it returns the same object you call it on?
Maybe your code should be:
PlayAudio *thisPlayAudio= [[PlayAudio alloc] init];
[thisPlaysAudio playFile:#"RockSnare"];
[thisPlaysAudio release];
or even
[[[[PlayAudio alloc] init] autorelease] playFile:(#"RockSnare")];
You are trying to immediately release object after creating. Probably, you also doing something wrong in playFile method. And your player won't play any file since you create and delete it in one scope. Try this:
PlayAudio *thisPlayAudio = nil;
- (IBAction) playKick {
if (thisPlayAudio){
[thisPlayAudio release]; thisPlayAudio = nil;
}
thisPlayAudio= [[PlayAudio alloc] init] autorelease];
[thisPlayAudio playFile:(#"RockSnare")];
}

xcode with IBAction

I’m trying to make an app in xcode. I have made a class called myApp.m and .h
In my .m I have these lines of code
- (void)loadApp
AlarmItem *item1 = [[[AlarmItem alloc] initWithTitle:#"TEST2"] autorelease];
NSMutableArray *items = [NSMutableArray arrayWithObjects:item1, nil];
RootViewController *rootController = (RootViewController *) [navigationController.viewControllers objectAtIndex:0];
rootController.items = items;
and in my RootViewController I have an this method:
- (IBAction)RefreshMyApp:(id)sender {
MyApp *myApp2 = [[[MyAppalloc] init] autorelease];
[myApp2 loadData];
}
What I’m trying to do is calling the method from the myApp class and displayed in the tableView, but I always get an empty cell.
Any help is appreciated.
Is this meant to get you your UIApplication singleton? (i'm guessing MyAppalloc is a typo and should be MyApp alloc)
MyApp *myApp2 = [[[MyApp alloc] init] autorelease];
if so then you should be doing it like this:
MyApp *myApp2 = (MyApp*)[UIApplication sharedApplication];
If this is not the case you need to make it clearer what MyApp is (your app delegate?)
I guess, your application running in singleton instance, if this is something kind of NSView or a particular control you want to refresh, you could call its particular refresh method like,
[NSTableView reload];
[NSTextField setString];
etc...