I am trying to make a simple soundboard app for the iphone, but have come across some troubles including implicit definition of function '...' is invalid in C99, about a few different functions.
My .h file looks like this:
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#interface ViewController : UIViewController
{
}
- (IBAction) Jesus: (id) sender;
#end
and my .m file code looks like this:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (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.
}
- (IBAction) NamedAction:(id)sender: (id) sender
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"Jesus",
CSFTR("WAV") NULL);
if (soundFileURLRef) {
CFStringRef url = CFURLGetString(soundFileURLRef);
NSLog(#"string for URl is %#", (__bridge NSString *) url);
}
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
#end
The error message I'm getting is:
Called object type 'int' is not a function or function pointer
- (IBAction) NamedAction:(id)sender: (id) sender
has to variables named the same, probably the 2nd is a typo:
- (IBAction) NamedAction: (id) sender
And
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"Jesus",
CSFTR("WAV") NULL);
possibly missing a comma before the NULL?
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"Jesus",
CSFTR("WAV"), NULL);
What function is CSFTR? Apparently the compiler has never heard of it, which is what it is telling (in a rather weird way. Before C99, using a function without declaration was in implicit declaration, C99 removed that).
Could it be that you are trying to use a macro with a name that is just slightly different?
I'd really recommend that you avoid using Core Foundation functions. Especially since NSBundle and CFBundle can behave differently. Core Foundation and ARC especially is a combination that can make your brain hurt and can lead to memory leaks or crashes, unless you really know what you are doing.
you forgot to add a framework to your project which i suspect is AudioToolBox
Add -Wno-implicit-function-declaration in Other warnings flag and you will be able to compile the code. Although its not a good solution but it will work.
Related
Here is the complete .m file :
#import "DevotionalView.h"
#implementation DevotionalView
#synthesize mytextview;
#synthesize mystring;
- {void} awakeFromNib {
NSURL *myurl = [NSURL URLWithString:#"http://www.myserver.com/text.txt"];
NSString *mystring = [NSString stringWithContentOfURL:myurl];
mytextview.text = mystring;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
The errors are: '#end' is missing in implementation context --where the #implementation DevotionalView is-- and at the {void} line it says Expected selector for objective-c method.
Thanks for taking the time to help!
The errors are: '#end' is missing in implementation context --where the #implementation DevotionalView is-- and at the {void} line it says Expected selector for objective-c method.
Also, at the end of the file it say "expected method body"
Seems to work fine in the tutorial I followed, but it will not compile in XCode 4.3.
I'm using Storyboard-- will this change the part about NIB? I apologize for my lack of knowledge-- still getting used to this.
Thanks for any help!
It looks like you have {}'s around the void in awakeFromNib they should be ()'s
Well, I finally worked around it-- from my searches it would appear that I had either messed up a delegate assignment or some such thing. So...(and you pros might groan at this) I opened up a new project (single view with a controller) and copied and pasted the controller, .h and .m files in, then used this code:
- (void)viewDidLoad
{NSError *error = nil;
NSURL *myurl = [NSURL URLWithString:#"http://www.myserver.com/test.txt"];
NSString *mystring = [NSString stringWithContentsOfURL:myurl encoding:NSUTF8StringEncoding error:&error];
newtext.text = mystring;
All is well!
I'm writing a simple static library for myself recently. It include some ui control, macro, and additions of cocoa touch class, but there's something wrong with my code, and I don't know how to solve it.
I did these steps:
create a cocoa touch static library project named Orange, just for test.
add a NSObject subclass named MyMath, implement code.
add 2 files for NSArray addition, implement code.
move the project directory to "/".
create a window based application named TestOrange.
drag the Orange.xcodeproj into TestOrange.
set header search paths to "/Orange/Orange"
set Build Phases like the image bellow showed.
when i run the TestOrange, it can print the result of MyMath, but crash immediately.
MyMath can work, but NSArrayAdditions can't work. I think there's something wrong with NSArrayAdditions.
anyone encountered this problem before? please help me.
thanks in advance.
all code have listed here.
MyMath
#interface MyMath : NSObject {
}
- (NSNumber*)AddA:(int)a B:(int)b;
#end
#implementation MyMath
- (NSNumber*)AddA:(int)a B:(int)b {
return [NSNumber numberWithInt:a+b];
}
#end
NSArrayAdditions
#interface NSArray (Additions)
- (NSNumber*)Double:(int)a;
#end
#implementation NSArray (Additions)
- (NSNumber*)Double:(int)a {
return [NSNumber numberWithInt:2*a];
}
#end
use libOrange
#import "TestOrangeAppDelegate.h"
#import "MyMath.h"
#import "NSArrayAdditions.h"
#implementation TestOrangeAppDelegate
#synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MyMath *mm = [[MyMath alloc] init];
NSLog(#"%#", [mm AddA:12 B:23]);
[mm release];
NSArray *ary = [[NSArray alloc] init];
NSLog(#"%#", [ary Double:13]);
[ary release];
[self.window makeKeyAndVisible];
return YES;
}
#end
Try adding -ObjC and -load_all to your "other linker flags" in your build settings.
Basically, categories on framework classes don't necessarily get linked in unless you specify this flag.
-load_all will force the loading of all compiled classes, which solves the problem.
I'm making a simple RSS feed iPhone app, and I run into this:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([stories count] == 0)
{
NSString * path = #"myfeedURL.rss";
[self parseXMLFileAtURL:path]; <-------Error Here
}
}
The method is defined after it is used. The Objective-C compiler is one-pass, so it doesn't have the declaration for parseXMLFileAtURL: yet. I present three ways of fixing this:
Define it before it is used:
-(void)parseXMLFileAtURL:(...)... {
...
}
-(void)viewDidAppear:(BOOL)animated {
...
}
Stick in your header:
#interface RootViewController ...
...
-(void)parseXMLFileAtURL:(...)...;
#end
Or stick it in a "class continuation":
#interface RootViewController()
-(void)parseXMLFileAtURL:(...)...;
#end
#implementation RootViewController
...
Class continuations are useful for things like "private" methods/properties and protocols — you can do #interface Foo()<BarDelegate> to avoid header spaghetti.
EDIT: And the name of the method suggests that it takes an NSURL*, but you're passing an NSString*. I would either change it to say "URLString" or make it take an NSURL*.
I am getting crazy over this error. Compiler is saying out of scope for an instance NSSString variable. Never had this thing before and used thousands of NSString instance variables!
Here is my class .h file
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
#import "Snapshot.h"
#interface RecordAudioViewController : UIViewController <AVAudioRecorderDelegate, AVAudioPlayerDelegate> {
NSString *filename;
}
#property (nonatomic, retain) NSString *filename;
- (IBAction) recordAudio;
- (IBAction) playAudio;
#end
Variable is synthesized properly. I initalize filename variable in viewDidLoad method. I want to use it in IBAction method recordAudio, but compiler always says out of scope? Why is that, is this a bug or something?
Here is .m code. viewDidLoad method where I set the filename instance variable:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *tmpDir = NSTemporaryDirectory();
filename = [NSString stringWithFormat: #"%.0f.%#", [NSDate timeIntervalSinceReferenceDate] * 1000.0, #"caf"];
NSLog(filename);
}
And the IBAction method
- (IBAction) recordAudio
{
NSLog(filename); // here I get out of scope message when moving over with mouse cursor and when steping over this line EXC_BAD_ACCESS
}
The entire .m file can be seen here: http://pastie.org/1021993
Actually, if you set filename = [NSString stringWithFormat...], the autoreleased result is NOT retained.
However, if you use self.filename = [NSString stringWithFormat...] it WILL retain the string. Kinda looks like the string is getting released out from under you because you're not retaining it.
You mentioned that you initialize the variable filename in the viewDidLoad method. if you mean nsstring alloc and init methods by initializing, i don't think that you are going the right way. It is not necessary to initialize a synthesized string, or more generically any strings. I'm not sure whether you meant this by initializing, but i gave my opinion based on the idea that i got from your Ques.
Is viewDidLoad actually happening? If it doesn't get called, that would perfectly explain the crash in recordAudio as it hasn't been initialised.
I am very familiar with writing VB based applications but am new to Xcode (and Objective C). I have gone through numerous tutorials on the web and understand the basics and how to interact with Interface Builder etc. However, I am really struggling with some basic concepts of the C language and would be grateful for any help you can offer. Heres my problem…
I have a simple iphone app which has a view controller (FirstViewController) and a subview (SecondViewController) with associated header and class files.
In the FirstViewController.m have a function defined
#implementation FirstViewController
- (void) writeToServer:(const uint8_t *) buf {
[oStream write:buf maxLength:strlen((char*)buf)];
}
It doesn't really matter what the function is.
I want to use this function in my SecondViewController, so in SecondViewController.m I import FirstViewController.h
#import "SecondViewController.h"
#import "FirstViewController.h"
#implementation SecondViewController
-(IBAction) SetButton: (id) sender {
NSString *s = [#"Fill:" stringByAppendingString: FillLevelValue.text];
NSString *strToSend = [s stringByAppendingString: #":"];
const uint8_t *str = (uint8_t *) [strToSend cStringUsingEncoding:NSASCIIStringEncoding];
FillLevelValue.text = strToSend;
[FirstViewController writeToServer:str];
}
This last line is where my problem is.
XCode tells me that FirstViewController may not respond to writeToServer.
And when I try to run the application it crashes when this function is called.
I guess I don't fully understand how to share functions and more importantly, the relationship between classes.
In an ideal world I would create a global class to place my functions in and call them as required.
Any advice gratefully received.
In the deklaration of your method:
- (void) writeToServer:(const uint8_t *) buf;
The - at the beginning of the declaration indicates, that it is an instant method. This means, you have to create an instance of your class to call it. If there were a +, the method would be a class method and you could call it the way you do in your code.
Example:
#interface MyClass
{ }
- (void) myInstanceMethod;
+ (void) myClassMethod;
#end
Then in some function:
[MyClass myClassMethod]; // This is ok
//[MyClass myInstanceMethod]; // this doenst't work, you need an instance:
MyClass *theInstance = [[MyClass alloc] init];
[theInstance myInstanceMethod];
In the line:
[FirstViewController writeToServer:str];
...you are sending the message writeToServer: to the FirstViewController class. Instead, you need to send it to a FirstViewController object. This means that you need to obtain a reference to a FirstViewController object and then send the object the writeToServer: message:
[firstViewControllerObject writeToServer:str];
However, because there is only one view active at a time on the iPhone, you should not be having FirstViewController and SecondViewController objects existing at the same time and communicating with each other. Instead, you should create independent classes to perform the required class and the active view controller should be interacting with these classes.
Note: "You are sending the message sayHello: to the object myObject" is just another way of saying "you are calling the writeToServer: method of the object myObject. (A "method" is like the object-oriented version of a function.)
I would recommend reading the Learning Objective-C and Learn Cocoa II tutorials on Cocoa Dev Central to learn more about Cocoa/Objective-C and object-oriented programming.
In your FirstViewController.h file, you must declare writeToServer as a method of FirstViewController object in the #interface section
#interface FirstViewController : UIViewController {
}
- (void) writeToServer:(NSString *) str;
#end
Secondly, the following message you send is invalid as FirstViewController writeToServer is not a class method and is only valid if called from an instantiation of the FirstViewController class.
FirstViewController *firstViewCnt = [[FirstViewController alloc] init];
[firstViewCnt writeToServer:str];
[firstViewCnt release];
Or something like that.
You need to write:
- (void) writeToServer:(const uint8_t *) buf;
in your FirstViewController.h file. This is a hint for the compiler that the function is available for that particular class. Your code would still work without this, because the actual function is implemented, but you get the warning because the compiler doesn't check the .m file for existing functions when you include the header from another source file.
if you want to call this method like this only declare writeToServer method as class method (static method in short...)
for that you have declare and define it like
+ (void) writeToServer:(const uint8_t *) buf;
+ (void) writeToServer:(const uint8_t *) buf {
[oStream write:buf maxLength:strlen((char*)buf)];
}
only difference is + sign instead of -
sign indicate that method is class method(static)
and - sign is for instance method (non static)
Second option is creat instance of FirstViewController and call the existing method
i.e
FirstViewController FirstViewControllerObj = [[FirstViewController alloc] init];
[FirstViewControllerObj writeToServer:str];
FirstViewController.h
#interface FirstViewController: UIViewController
- (void)GetItNow;
FirstViewController.m
- (void)GetItNow{
NSLog(#"I acheived"); }
- (IBAction)goToSecondView:(id)sender {
SecondViewController* Second= [[SecondViewControlleralloc] initWithNibName:#"SecondViewController" bundle:nil];
rqVC.addId = self.addId;
[self.view addSubview:Second.view];
}
SecondViewController.h
#property (nonatomic, assign) id delegate;
SecondViewController.m
- (IBAction)Action_LoadFunds:(id)sender {
[self.view removeFromSuperview];
[_delegate GetItNow];
}