I have to generate a doc for Xcode's project Objective-C.
I have an error anonymous type. I think headerdoc doesn't like #interface section. Can someone resolve that?
My apologies for some grammar mistakes, I have a Xcode's project Objective-C, I want generate a doc with a script (I'm not at my work so I will try explain the problem). In my project I have a class x
.h
/*! headerdoc comment */
#interface x: NSObject
#end
.m
#import x.h
#interface x(){
/*! headerdoc comment */
NSString *_xID;
}
#end
#implementation x
/*! headerdoc comment */
-(void)aMethod{
}
#end
And when I run, I have an error "anonymous type", and when I removed #interface section in .m it's working.
Related
I have a protocol defined in Swift:
#objc public protocol UploadProtocol: class {
func isUploaded() -> Bool
...
}
I'm importing my ProjectName-Swift.h file in my ProjectName_Prefix.pch file (old project).
In Objective-C I have a category on a class which implements the protocol. I'm trying to figure out how to let the compiler know about that implementation. This is what I have been doing:
// Person+Upload.h
#import "Person.h"
#interface Person (Upload)
- (BOOL)isUploaded;
#end
// Person+Upload.m
#import "Person+Upload.h"
#implementation Person (Upload)
...
#end
This gives me:
Cannot find protocol definition for 'UploadProtocol'
I can only think of three other ways of setting this up and all of them have problems. What am I missing?
First Way (Apple Recommended)
In Using Swift with Cocoa and Objective-C (Swift 2.2), Apple says, "An Objective-C class can adopt a Swift protocol in its implementation (.m) file by importing the Xcode-generated header for Swift code and using a class extension." But their example is for a standard class. If I try to do this with my category:
// Person+Upload.h
#import "Person.h"
#interface Person (Upload)
- (BOOL)isUploaded;
#end
// Person+Upload.m
#import "Person+Upload.h"
#interface Person (Upload) <UploadProtocol>
#end
#implementation Person (Upload)
...
#end
This results in:
Duplicate definition of category 'Upload' on interface 'Person'
Second Way
Ok, so I want to avoid defining the upload class twice. So I'll remove it from the .h.
// Person+Upload.h
#import "Person.h"
#interface Person ()
- (BOOL)isUploaded;
#end
// Person+Upload.m
#import "Person+Upload.h"
#interface Person (Upload) <UploadProtocol>
#end
#implementation Person (Upload)
...
#end
In this case I get:
Category is implementing a method which will also be implemented by its primary class
I'm currently declaring the method in the .h so that other classes can call some of those methods without casting to the protocol to access that method.
Third Way
If I leave the category name in the .h but take it off in the .m
// Person+Upload.h
#import "Person.h"
#interface Person (Upload)
- (BOOL)isUploaded;
#end
// Person+Upload.m
#import "Person+Upload.h"
#interface Person () <UploadProtocol>
#end
#implementation Person (Upload)
...
#end
Then I get:
Category is implementing a method which will also be implemented by its primary class
Is the only solution to cast it to the protocol every time? Adding this type of line in multiple places seems like a code smell:
Person <Upload> *s = (Person <Upload> *)self;
Any other solutions?
Thanks for the interesting question!
Your initial approach will actually work with an addition of a forward declaration of the protocol:
// Person+Upload.h
#import "Person.h"
#protocol UploadProtocol; // NOTE THIS!!!
#interface Person (Upload) <UploadProtocol>
//- (BOOL)isUploaded; // This is not really needed
#end
// Person+Upload.m
#import "Person+Upload.h"
#import "...-Swift.h" // IMPORTANT!!!
#implementation Person (Upload)
// HERE you implement isUploaded, of course.
...
#end
This will still cause a compiler warning Cannot find protocol definition for 'UploadProtocol', but it should work.
The Apple-recommended way also works, the Duplicate definition of category is just a warning, but Person won't be recognized as conforming to the protocol by Swift code, even though its conformance will be recognized by Objective-C. The initial approach will be fine in Swift, too.
Hi I'm new to Swift but experienced with Objective-C.
I have a project that uses both Swift and Objective-C files (bridging and all).
Say I have a protocol called "fooProtocol" and a class "foo" that implements it. I am trying to pass an object of type "fooProtocol" from the Swift file as a parameter to the function inside the Objective-C file.
here is the Objective-C function inside class "tester":
-(void)setWithFoo:(id<fooProtocol>*)_foo{
}
here is the Swift code:
var myObject:fooProtocol = foo.init()
var objcObject:tester = tester.init()
objcObject.setWithFoo(_foo: myObject)
It first says "Cannot convert value of type "fooProtocol" to expected argument type "AutoreleasingUnsafeMutablePointer (obviously because it needs to be passed by reference, so...)
I then tried casting the parameter to this:
tester.setWithFoo(_foo: AutoreleasingUnsafeMutablePointer<fooProtocol>(myObject))
Now the error reads: "Cannot invoke initializer for type 'AutoreleasingUnsafeMutablePointer with an argument list of type '(fooProtocol)'
I have tried many more permutations and variations but I simply cannot stop the compiler error. For such a simple procedure as passing a polymorphic variable to a function in Objective-C file that expects that protocol id, Swift has made it a nightmare.
...Any help would be appreciated, thanks!
=== EDIT ===
Here are the declarations for the classes, now starting properly with caps
In the "FooProtocol.h" file:
#protocol FooProtocol
#end
In the "Foo.h" file:
#import <Foundation/Foundation.h>
#import "FooProtocol.h"
#interface Foo : NSObject <FooProtocol>
#end
In the "Foo.m":
#import "Foo.h"
#implementation Foo
#end
The "FooProtocol.h" file:
#import <Foundation/Foundation.h>
#protocol FooProtocol
#end
The "Tester.h" file:
#import <Foundation/Foundation.h>
#import "FooProtocol.h"
#interface Tester : NSObject
-(void)setWithFoo:(id<FooProtocol>*)_foo;
#end
The "Tester.m" file:
#import "Tester.h"
#implementation Tester
-(void)setWithFoo:(id<FooProtocol>*)_foo{
//do something with _foo
}
#end
And again the Swift code that can't compile:
var myObject:FooProtocol = Foo.init()
var objcObject:Tester = Tester.init()
objcObject.setWithFoo(AutoreleasingUnsafeMutablePointer<FooProtocol>(myObject))
You probably don't mean to say this:
-(void)setWithFoo:(id<FooProtocol>*)_foo;
It is very unusual to see an id* in Objective-C. In fact, it's so unusual that in all my years of programming Cocoa, I have never seen one.
You probably mean this:
-(void)setWithFoo:(id<FooProtocol>)_foo;
And then you will be able to say, on the Swift side:
objcObject.setWithFoo(myObject)
I'm having a problem when I try to add a second protocol. The first one is working just fine. So I created a test application to try out using two protocols (because I'm still learning how to use protocols). I do not know why I am having so much trouble understanding protocols. I've even gone through tutorials and still struggle with them.
My first issue when I tried to add the second protocol and use it I received the following error:
Assigning to ‘id’ from incompatible type ‘ *const _strong'
But, let's ignore that for now, because my test application is giving me this error for both protocols in my test app:
Cannot find protocol declaration
So, I will post the code for my test application, because I MUST understand the basics before tackling more difficult issues.
DelegateA Header
#import <Foundation/Foundation.h>
#protocol IDDelegateADelegate <NSObject>
#end
#interface IDDelegateA : NSObject
//other properties here
#property (nonatomic, assign) id<IDDelegateADelegate> delegateA;
#end
DelegateA Implementation
#import "IDDelegateA.h"
#implementation IDDelegateA
#synthesize delegateA;
//other methods and properties go here
#end
DelegateB Header
#import <Foundation/Foundation.h>
#protocol IDDelegeteBDelegate <NSObject>
#end
#interface IDDelegeteB : NSObject
//other properties here
#property (nonatomic, assign) id<IDDelegeteBDelegate> delegateB;
#end
DelegateB Implementation
#import "IDDelegeteB.h"
#implementation IDDelegeteB
#synthesize delegateB;
//other methods and properties go here
#end
The test class Header that uses these delegates
#import <Foundation/Foundation.h>
#import "IDDelegateA.h"
#import "IDDelegeteB.h"
#interface IDTestingDelegates : NSObject <IDDelegateA, IDDelegateB>
#end
Right here I receive the Cannot find protocol declaration error for both delegates. I've been searching on SO as well as going through tutorials and sample code. Best answer on SO was here. But I'm just not getting what I'm doing wrong. Can somebody please point out what I am missing here?
#interface IDTestingDelegates : NSObject <IDDelegateA, IDDelegateB>
should be
#interface IDTestingDelegates : NSObject <IDDelegateADelegate, IDDelegeteBDelegate>
You have to list the protocols in <...>, not interfaces.
#interface declares a class, while the ClassName <X> syntax expects X to be a protocol (in your declaration of IDTestingDelegates).
Not sure exactly what you were trying to achieve here.
Anyone know of an example project of a Objective-C project calling Objective-C++ code.
I've read all the stackoverflow q's about getting one to call the other but no luck.
Would help if I had a code sample that worked.
The Obj-C++ I have is a lib .a and some c++ headers. Thats all.
Here's example project I made, it's actually easy to undestand, you can just rename your classes from .m to .mm or in project settings set "Compile sources as" to Objective-C++. I have had some trouble with C++ headers which didn't have C++ implementation as well - changing settings to compile everything as Objective-C++ helped.
Here's the code https://github.com/libec/StackOverflow/tree/master/03-Obj-C%2B%2B
Here's a contrived example. Without more information about what you're trying to do, or the errors you're receiving, it will be impossible to guide you much further. Remember that any code that calls C++/Objective-C++ code or imports a header that includes C++-isms must be compiled as Objective-C++ (use the .mm extension and Xcode will automatically do the right thing).
/*Objcpp.h
**********/
#interface MyClass : NSObject
{}
- (void)myMethod;
#end
/*Objcpp.mm
***********/
#import "Objcpp.h"
#implementation MyClass
- (void)myMethod {
//some c++ and/or objective-c calls
}
#end
/*myobjc.h
***********/
#interface MyObjCClass : NSObject
{}
- (void)someMethod;
#end
/*myobjc.mm
***********/
#import "myObjCClass.h"
#import "Objcpp.h"
#implementation MyObjCClass
- (void)someMethod {
MyClass *o = [[MyClass alloc] init];
[o myMethod];
}
#end
I need to develop an application which has a interface which implements methods of 3 protocols.
Assume protocol A extends protocol B and protocol C, and interface implements protocol A.
This is how my code looks,
// This is in MyClass.h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "protocol_A"
#interface MyClass : NSObject <protocol_A>
{
}
#end
//This is MyClass.m file
#import "MyClass.h"
#implementation myClass
-(void)methodinA
{
NSLog(#"I'm in protocol_A");
}
}
-(void)methodinB
{
NSLog(#"I'm in protocol_B");
}
-(void)methodinC
{
NSLog(#"I'm in protocol_C");
}
#end
//This is protocol_A.h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "protocol_B.h"
#import "protocol_C.h"
#protocol protocol_A <protocol_B, protocol_C>
-(void)methodinA;
#end
//This is in protocol_B.h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#protocol protocol_B
-(void)methodinB;
#end
//This is in protocol_C.h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#protocol protocol_C
-(void)methodinC;
#end
i'm getting an exception , and my app is getting crashed...
***Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyClass 0X323nm31>setvalue:forundefinedKey:]:this class is not key value coding-compilant for the key window'.
Plz Tel me how to solve this problem??
So where you're getting this from (and the reason you're getting it 3 times) is you've got a mistake in your protocol definitions. You have:
//This is in protocol_C.h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#protocol protocol_C
{
}
-(void)methodinC;
#end
You can't declare class members in a protocol: only methods. Because of this, you don't need (and, as you've discovered) can't have the curly braces in the protocol definition. As such, you need this for your protocol definitions:
//This is in protocol_C.h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#protocol protocol_C
-(void)methodinC;
#end
Removing those should solve your issue.
When making new files, I always go through Xcode's new-class-files process, as it frequently gives you lots of convenient stuff. Here is the contents of a new protocol_D declaration fresh from Xcode:
#import <Cocoa/Cocoa.h>
#protocol protocol_D
#end
Hope this helps!
TL;DR: Protocol definitions can't have curly-braces anywhere in them.
Protocols generally go in a .h file; always go in a .h file if you plan on using them anywhere.
Just like everything else, you need to #import the .h file that contains the definition of the protocol before you use it.
So, in MyClass.h (it really should be capitalized -- Classes are always capitalized in Objective-C), #import the various protocol .h files.
Your protocol_A.h file declares conformance to protocol_B and protocol_C, yet you haven't imported the headers for protocol_B and protocol_C. This means that you are declaring conformance to protocols that as far as the compiler is concerned, don't exist in protocol_A.h. You need to import the headers:
In protocol_A.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "protocol_B.h" //note these new imports
#import "protocol_C.h"
#protocol protocol_A <protocol_B, protocol_C>
-(void)methodinA;
#end
Also see Apple's Communicating with Objects, which discusses delegates, protocols, and selectors. Though its listed under Mac OS X, most (if not all) appears to apply to iOS also.