iPhone SDK - Call Objective C function - objective-c

i would like to create a function called "playSound" with one (but later two parameters - one, which is the filename and one, which is the musictype (mp3,...))
but i cant get the paramter working in my function...please help me
here's my code
//
// MainView.m
//
// Created by Christopher Fuchs on 26.01.11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "MainView.h"
#import <AVFoundation/AVAudioPlayer.h>
#import <AVFoundation/AVFoundation.h>
#implementation MainView
void playSound(char filename){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Mein Alert" message:filename delegate:nil cancelButtonTitle:#"Abbrechen" otherButtonTitles:nil];
[alert show];
[alert release];
}
- (IBAction)PlayFatGuyWalking:(id)sender {
playSound(#"MusicFile");
}
#end
For now, i just added an alert instead of the playing sound framework
the paramater is called "filename" and should be called as message of the alert
thanks in advance
greez

- (void)playSound:(NSString *)filename {
// method body
}
// calling
[self playSound:#"MusicFile"];

Make this line:
void playSound(char filename)
into this:
void playSound(NSString *filename)
The # "foo" construction says "this is an NSString".
Also, if you want to keep it a C function, you might want to move it out of the #implementation block.
You will find that virtually everything asking for a string in Cocoa will want an NSString, and not a char *.
Oh yeah, and the (char filename) won't work in plain C either, that a single byte variable, not a pointer to a potential string.

Related

NSSpeechRecognizer and .delegate=self; Problems

I've run into an issue with this little Objective-C project I'm doing and it's proving to be a bit of a roadblock. I'm playing around with Apple's NSSpeechRecognizer software on El Capitan, and I'm trying to get this guy running properly so that when the riddle I give it is posed to the user, the user can respond with a word to "do something cool". As it stands right now, the delegate method:
-(void) speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(NSString *)command { ... }`
is never even called, even though it appears the recognition icon is correctly detecting the answer to the riddle.
The problem is that your main function has a loop that is continually checking whether the speech has been recognizing. You are not giving NSSpeechRecognizer a chance to actually deliver any messages to you.
Your app needs to let the main "run loop" run, so it can deliver messages. Normally, in an OS X app, your main would just call NSApplicationMain, which does this for you.
Your code is effectively this:
#interface RecognizerDelegate : NSObject <NSSpeechRecognizerDelegate>
#property (nonatomic) NSSpeechRecognizer *recognizer;
#property (nonatomic) BOOL didRecognize;
#end
#implementation RecognizerDelegate
- (id)init
{
if ((self = [super init])) {
self.didRecognize = NO;
self.recognizer = [[NSSpeechRecognizer alloc] init];
self.recognizer.listensInForegroundOnly = NO;
self.recognizer.blocksOtherRecognizers = YES;
self.recognizer.delegate = self;
self.recognizer.commands = #[ #"hello" ];
[self.recognizer startListening];
}
return self;
}
- (void)speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(NSString *)command
{
self.didRecognize = YES;
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool
{
RecognizerDelegate *recognizerDelegate = [[RecognizerDelegate alloc] init];
while (recognizerDelegate.didRecognize == NO) {
// do nothing
}
NSLog(#"Recognized!");
}
return 0;
}
That while loop is doing nothing useful, just running your CPU in a loop and wasting time and energy. You are not letting any other code in NSSpeechSynthesizer, or any of the system frameworks like Foundation or AppKit, get the chance to do anything. So, nothing happens.
To fix this in the short term: you can let the main run loop run for a little while in each pass through the loop. This code would let the system run for a second, then would return to your code, so you could check again:
while (recognizerDelegate.didRecognize == NO) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
}
The longer-term fix would be to move your code out of main and to structure it like a real OS X app. Instead of using a loop to poll a condition like recognizerDelegate.didRecognize, you would just trigger the "next thing" directly from delegate methods like -speechRecognizer:didRecognizeCommand:, or you would use things like NSTimer to run code periodically.
For more details, see the Apple doc Cocoa Application Competencies for OS X, specifically the "Main Event Loop" section.
I had the same problem using NSSpeechRecognizer. The callback function:
func speechRecognizer(_ sender: NSSpeechRecognizer,
didRecognizeCommand command: String) {}
...was never called, even though everything appeared to be working.
There were three things I changed to get the code working.
1) I had to enable the entitlement in my "sandboxed" mode application to allow for microphone use.
... I also did these other two things, as well.
2) I added the "Privacy - Microphone Usage Description" in the info.pList, and set the string value to "I want to listen to you speak"
3) I added the "Privacy - Speech Recognition Usage Description" in the info.pList, and set the string value to "I want to write down what you say"

CNUI ERROR Selection predicates are set but the delegate does not implement contactPicker:didSelectContact:

I try to use the new iOS 9.0 CNContactPickerViewController to select a contact in objective-C. I set the delegate and implement the CNContactPickerDelegate methods.
#import ContactsUI;
#import Contacts;
//-----------------------------------------------------------------------
- (void) presentContacts
{
CNContactPickerViewController *contactPicker = [[CNContactPickerViewController alloc] init];
contactPicker.delegate = self;
contactPicker.predicateForEnablingContact = [NSPredicate predicateWithFormat:#"familyName LIKE[cd] 'smith'"];
contactPicker.predicateForSelectionOfContact = [NSPredicate predicateWithFormat:#"TRUEPREDICATE"];
[_myViewController presentViewController:contactPicker animated:YES completion:nil];
}
//-----------------------------------------------------------------------
- (void) contactPickerDidCancel: (CNContactPickerViewController *) picker
{
NSLog(#"didCancel");
}
//-----------------------------------------------------------------------
- (void) contactPicker: (CNContactPickerViewController *) picker
didSelectContact: (CNContact *) contact
{
NSLog(#"didSelectContact"):
}
//-----------------------------------------------------------------------
- (void) contactPicker: (CNContactPickerViewController *) picker
didSelectContactProperty: (CNContactProperty *) contactProperty
{
NSLog(#"didSelectProperty");
}
//-----------------------------------------------------------------------
The contacts picker is presented with 'smith' selectable but I get the following message:
[CNUI ERROR] Selection predicates are set but the delegate does not implement contactPicker:didSelectContact: and contactPicker:didSelectContactProperty:. Those predicates will be ignored.
And I never get any log from the delegate methods. It behaves exactly as the line
contactPicker.delegate = self;
is ignored. Even I click on the "cancel" button in the picker, I don't get my "didCancel" message but I get another message:
plugin com.apple.MobileAddressBook.ContactsViewService invalidated
I found in https://forums.developer.apple.com/thread/12275 somebody with the similar problem in swift and he solved it telling us: "So I found that the ContactsPicker I was calling was in the wrong module" but I do not understand how we can get the wrong module and how to call the "right" module.
I have the same problem on the simulator and on a real device (iPad).
Thanks to Joel in my related question With CNContactPickerViewController in iOS 9.0, how to enable/disable single or multiple selection?, I found that I just forgot to store the CNContactPickerViewController in a property that exists the time the user make the selection.
So my code becomes:
- (void) presentContacts
{
_contactPicker = [[CNContactPickerViewController alloc] init];
contactPicker.delegate = self;
...
}

how to call cocos2d-js method from objective-c

i am using cocos2d-js , that's a in purchase app,when purchase success ,i need to notify the message to cocos2d-js to update ui or something else,
i know call objective-c from cocos2d-js is like:
in js:
jsb.reflection.callStaticMethod("objective-cClass","methodName:", "parm");
but,how to call cocos2d-js from objective-c...
May it help someone, as we know, objective-c can easily call c++ methods, so we can use like this:
jsval ret;
ScriptingCore::getInstance()->evalString("CommonFun.setDiamond(88)", &ret);
and dont forget include head file, for cocos2d-x 3.8:
#include "cocos/scripting/js-bindings/manual/ScriptingCore.h"
1:how js call objc methods like this, js call only static method
(1)//NativeOcClass.mm filename
import <Foundation/Foundation.h>
#interface NativeOcClass : NSObject
+(BOOL)callNativeUIWithTitle:(NSString *) title andContent:(NSString *)content;
#end
#implement NativeOcClass
+(BOOL)callNativeUIWithTitle:(NSString *) title andContent:(NSString *)content{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:content delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[alertView show];
return true;
}
#end
(2)for js file
var ret = jsb.reflection.callStaticMethod("NativeOcClass",
"callNativeUIWithTitle:andContent:",
"cocos2d-js",
"Yes! you call a Native UI from Reflection");
2:objc call js method
(1)js method,e.g.//Test.js
var Test={
myMethod:function(){
console.log("call js");
}
}
(2)objc //filename.mm
#include "cocos/scripting/js-bindings/manual/ScriptingCore.h"
....
-(void)callJsMethod
{
jsval ret;
ScriptingCore::getInstance()->evalString("Test.myMethod()", &ret);
}

ShareKit: Customizing text for different sharers (SHKActionSheet)

According to the official FAQ from ver.2 to customize your text/content depending on what sharer was selected by the user, you need:
subclass from SHKActionSheet and override
dismissWithClickedButtonIndex
set your new subclass name in
configurator (return it in (Class)SHKActionSheetSubclass;).
It doesn't work for me. But even more: I put
NSLog(#"%#", NSStringFromSelector(_cmd));
in (Class)SHKActionSheetSubclass to see if it's even got called. And it's NOT ;(( So ShareKit doesn't care about this config option...
Has anybody worked with this before?
thank you!
UPD1: I put some code here.
Here's how my subclass ITPShareKitActionSheet looks like. According to the docs I need to override dismissWithClickedButtonIndex:animated:, but to track if my class gets called I also override the actionSheetForItem::
+ (ITPShareKitActionSheet *)actionSheetForItem:(SHKItem *)item
{
NSLog(#"%#", NSStringFromSelector(_cmd));
ITPShareKitActionSheet *as = (ITPShareKitActionSheet *)[super actionSheetForItem:item];
return as;
}
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animate
{
NSLog(#"%#", NSStringFromSelector(_cmd));
NSString *sharersName = [self buttonTitleAtIndex:buttonIndex];
[self changeItemForService:sharersName];
[super dismissWithClickedButtonIndex:buttonIndex animated:animate];
}
And here's what I do in code to create an action sheet when user presses 'Share' button:
- (IBAction)shareButtonPressed:(id)sender
{
// Create the item to share
SHKItem *item = [SHKItem text:#"test share text"];
// Get the ShareKit action sheet
ITPShareKitActionSheet *actionSheet = [ITPShareKitActionSheet actionSheetForItem:item];
// Display the action sheet
[actionSheet showInView:self.view]; // showFromToolbar:self.navigationController.toolbar];
}
When I run this code, press 'Share' button and select any sharer I expect to get two lines in log:
actionSheetForItem: - custom action sheet got created
dismissWithClickedButtonIndex:animated: - custom mechanics to
process action sheet's pressed button got called.
But for some reason I get only the first line logged.
I was having the same issues but I've suddenly got it to call my Subclass successfully.
Firstly My Configurator is setup as so:
-(Class) SHKActionSheetSubclass{
return NSClassFromString(#"TBRSHKActionSheet");
}
Now My Subclass:
.h File
#import "SHKActionSheet.h"
#interface TBRSHKActionSheet : SHKActionSheet
#end
.m implementation override:
#import "TBRSHKActionSheet.h"
#import "SHKActionSheet.h"
#import "SHKShareMenu.h"
#import "SHK.h"
#import "SHKConfiguration.h"
#import "SHKSharer.h"
#import "SHKShareItemDelegate.h"
#implementation TBRSHKActionSheet
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
+ (SHKActionSheet *)actionSheetForItem:(SHKItem *)i
{
NSLog(#"%#", NSStringFromSelector(_cmd));
SHKActionSheet *as = [self actionSheetForType:i.shareType];
as.item = i;
return as;
}
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
{
NSInteger numberOfSharers = (NSInteger) [sharers count];
// Sharers
if (buttonIndex >= 0 && buttonIndex < numberOfSharers)
{
bool doShare = YES;
SHKSharer* sharer = [[NSClassFromString([sharers objectAtIndex:buttonIndex]) alloc] init];
[sharer loadItem:item];
if (shareDelegate != nil && [shareDelegate respondsToSelector:#selector(aboutToShareItem:withSharer:)])
{
doShare = [shareDelegate aboutToShareItem:item withSharer:sharer];
}
if(doShare)
[sharer share];
}
// More
else if ([SHKCONFIG(showActionSheetMoreButton) boolValue] && buttonIndex == numberOfSharers)
{
SHKShareMenu *shareMenu = [[SHKCONFIG(SHKShareMenuSubclass) alloc] initWithStyle:UITableViewStyleGrouped];
shareMenu.shareDelegate = shareDelegate;
shareMenu.item = item;
[[SHK currentHelper] showViewController:shareMenu];
}
[super dismissWithClickedButtonIndex:buttonIndex animated:animated];
}
Finally on my implementation file I've not modified the call to SHKActionSheet as Vilem has suggested because of some dependancies that seemed to cause conflicts for me.
So this is my caller (straight from tutorial):
NSURL *url = [NSURL URLWithString:#"http://getsharekit.com"];
SHKItem *item = [SHKItem URL:url title:#"ShareKit is Awesome!" contentType:SHKURLContentTypeWebpage];
// Get the ShareKit action sheet
SHKActionSheet *actionSheet = [SHKActionSheet actionSheetForItem:item];
// ShareKit detects top view controller (the one intended to present ShareKit UI) automatically,
// but sometimes it may not find one. To be safe, set it explicitly
[SHK setRootViewController:self];
// Display the action sheet
[actionSheet showFromToolbar:self.navigationController.toolbar];
This Calls no problems for me.
edit: by far the best way to achieve this is to use SHKShareItemDelegate. More info is in ShareKit's FAQ.

Objective C : Misunderstanding with the didFinishPLaying delegate method

I want to get familiar with the Objective C/Interface Builder programming on mac OSX. I'm usually working with sounds, so I'm trying to code a simple audio player, using the NSSound class.
I already managed to create a basic application that loads a sound by clicking an "Importer" button, and then play it by clicking a "Lire" button.
Here is my problem : I want to have a TextField in the window that displays "Ça joue Simone !..." when the sound is played, and nothing when the sound is finished playing.
When clicking the "Lire" button, the message I want is successfully displayed, but it stays there even after the sound is finished playing.
That's why I guess I have a misunderstanding on how to use the didFinishPLaying delegate method.
Does anybody have a hint ?
//
// ControleurLecteur.h
// LecteurSon
//
#import <Cocoa/Cocoa.h>
#interface ControleurLecteur : NSObject {
NSSound *son ;
IBOutlet NSTextField *infoTextField ;
IBOutlet NSTextField *cheminField ;
IBOutlet NSTextField *durationField ;
}
-(IBAction)lireSon:(id)sender ;
-(IBAction)importerSon:(id)sender ;
-(IBAction)son:(NSSound *)son didFinishPlaying:(BOOL)bienjoue;
#end
//
// ControleurLecteur.m
// LecteurSon
//
#import "ControleurLecteur.h"
#implementation ControleurLecteur
-(IBAction)importerSon:(id)sender {
NSString *Chemin = [[NSString alloc] initWithString:(NSString *)#"epno"] ;
son = [[NSSound soundNamed:Chemin] retain];
// Limiter l'affichage de la durée à 3 chiffres après la virgule
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMaximumFractionDigits:3];
[[durationField cell] setFormatter:numberFormatter];
// Remplissage du champ de texte durée
[durationField setFloatValue:[son duration]] ;
}
-(IBAction)lireSon:(id)sender {
BOOL bienjoue;
bienjoue = [son play];
bienjoue = TRUE;
[infoTextField setStringValue:#"Ça joue Simone !..."];
son:didFinishPlaying:bienjoue;
}
-(IBAction)son:(NSSound *)son didFinishPlaying:(BOOL)bienjoue {
[infoTextField setStringValue:#""] ;
}
#end
You must set the delegate of son after you create it:
son = [[NSSound soundNamed: Chemin] retain];
[son setDelegate: self];
Otherwise, son has no idea where to send its delegate messages.
You must also take care to preserve the English names of delegate messages. If you translate them into French, they won't be understood by Objective-C (the names of arguments can be anything, however.) Instead of:
-(IBAction)son:(NSSound *)son didFinishPlaying:(BOOL)bienjoue
Use:
-(void)sound:(NSSound *)son didFinishPlaying:(BOOL)bienjoue
Most developers I know opt to code entirely in English, since almost all programming languages use English-based keywords, class names, etc., and combining their native languages with English tends to just make a difficult-to-read mess.
You forgot delegate:
#interface ControleurLecteur : NSObject <Son> {
}