How do i interface my objc program with an objc++ library? - objective-c

I have an objc program and i would like to use a widget that is written in objc++ (namely https://launchpad.net/scintilla-cocoa). How do i go about this? Basically i want a new window controller object to interface with this objc++ library to define a scintilla text editor widget. Simply creating a new 'objc class' and accessing the library from there generates a bunch of errors related to the C++ class keyword and so on.
Thanks in advance

Since I'm the one who put you into the (hopefully rewarding :-)) trouble of using Scintilla, here I am.
Let's say we create a ScintillaView subclass, named ppScintillaEditor.
The file should have an .mm extension (e.g. ppScintillaEditor.mm)
The code would be roughly like this...
Interface
#import "Scintilla/ScintillaView.h"
#interface ppScintillaEditor : ScintillaView
{
// your iVars
}
// your properties / methods / whatever
Now, as for the implementation part, remember to put some initialization method to set up the view properly (as in the example accompanying Scintilla-cocoa; I mean the Test project)
Sidenote : Of course, you can create subclasses, categories or whatever on top the ScintillaView class, pretty much based on what you need - I, for example, have create a separate Category just in order to group there some ScintillaView specific commands (sooner or later, you'll notice that for some more advanced Scintilla manipulations, although it's there, it may need some polishing to be a bit more cocoa-friendly, so here you go...)
Now, last but not least...
To resolve the "bunch of errors related to the C++ class keyword and so on", as I've shown in my other video-response to your comment, all you have to do is :
Go to your project's Build Settings
Under Apple LLVM Compiler 3.0 - Preprocessing
Option Preprocessor Macros
Add to both Debug and Release :
SCI_NAMESPACE SCI_LEXER
And that's it. :-)
Hint : The above are defined by Scintilla to avoid clashes between C and non-C elements, like above... so, all it takes is to notify the preprocessor and the rest is taken care of....

you would create an objc class which has the interface your app needs, then implement and add the ivars and implement -- all behind a compilation firewall so the objc++ sources are not included in the header. your implementation would provide any necessary conversions.
it is like you have already done, but you remove the scintilla headers from the header for your wrapper -- they are visible only to your wrapper's implementation.
Update
To illustrate one possible approach:
MONScintillaWrapper.h
// no c++/scintilla sources should be included in this header
#import <Foundation/Foundation.h>
#interface MONScintillaWrapper : NSObject
- (void)setBackgroundColor:(NSColor *)pColor;
#end
MONScintillaWrapper.mm
#import "MONScintillaWrapper.h"
#implementation MONScintillaWrapper
{
scintilla::t_thing scintillaThing;
}
- (void)setBackgroundColor:(NSColor *)pColor
{
...convert pColor to a scintilla color and pass that to scintillaThing...
}
#end

Related

How can I add forward class references used in the -Swift.h header?

I'm integrating Swift code into a large Objective-C project, but I'm running into problems when my Swift code refers to Objective-C classes. For example, suppose I have:
An Objective-C class called MyTableViewController
An Objective-C class called DeletionWorkflow
I declared a Swift class as follows:
class DeletionVC: MyTableViewController {
let deleteWorkflow: DeletionWorkflow
...
}
If I now try to use this class by importing ProjectName-Swift.h into Objective-C code, I get undefined symbol errors for both MyTableViewController and DeletionWorkflow.
I can fix the problem in that individual source file by importing DeletionWorkflow.h and MyTableViewController.h before I import ProjectName-Swift.h but this doesn't scale up to a large project where I want my Swift and Objective-C to interact often.
Is there a way to add forward class references to ProjectName-Swift.h so that these errors don't occur when I try to use Swift classes from Objective-C code in my app?
You can create another header file that forward declares or imports the necessary classes, and then imports ProjectName-Swift.h. For example, create a file named ProjectName-Swift-Fixed.h with the contents:
// ProjectName-Swift-Fixed.h
// Forward declarations for property classes
#class DeletionWorkflow;
// Imports for superclasses
#import "MyTableViewController.h";
#import "ProjectName-Swift.h"
Then, instead of #import "ProjectName-Swift.h" in your codebase, use #import "ProjectName-Swift-Fixed.h.
This is a little silly, but it sounds like your "workaround" is what Apple intended, at least for now. From the interoperability guide:
If you use your own Objective-C types in your Swift code, make sure to import the Objective-C headers for those types prior to importing the Swift generated header into the Objective-C .m file you want to access the Swift code from.
In this devforums thread, someone mentioned they already filed a bug in Radar. You probably should too.

Objective C: Properties Not Found In Forward Declaration Vs Parse Issue: Expected A Type

I have a singleton class called DataManager. This class is used by several other classes to deal with loading and saving plist files.
I am adding the ability for DataManager to save screenshots as well as plist files. This requires me to load the view I wish to take a screenshot of. The view I'm loading comes from a controller that imports DataManager.
Obviously this is circular dependency, so I used:
#class GardenView;
However, this resulted in the following errors:
Receiver 'GardenView' for class message is a forward declaration
Receiver type 'GardenView' for instance message is a forward
declaration Property 'bounds' cannot be found in forward class
object 'GardenView' Property 'layer' cannot be found in forward
class object 'GardenView'
This seems like it can't find properties inherited from the UIView superclass. Is this true of forward class declarations?
If I use the standard #import instead of #class, I get:
Parse Issue: Expected A Type
for the methods in GardenView referencing Plant (which I am importing just fine):
- (void) addPlantToView: (Plant*) plant;
- (void) addPlantToGarden: (Plant*) plant;
- (void) addPlantToViewAndGarden: (Plant*) plant;
The Plant class DOES import the DataManager, but if I change it to #class, I get:
No known class method for selector 'sharedDataManager'
What is the solution for this problem? The class method is there in the header file (+sharedDataManager). Am I doing something completely wrong?
You haven't made it clear where exactly you're doing the imports vs #class. And I think that's causing confusion. Here's what you want to do:
In GardenView.h, use #class Plant
In Plant.h, use #class GardenView
In GardenView.m, use #import "Plant.h"
In Plant.m, use #import "GardenView.m"
This breaks the circular dependency in the headers, but still allows the implementations to see the full information of the dependent class.
Now the reason why #class alone isn't sufficient is because all #class Foo does is it tells the compiler "There exists a class named Foo", without telling it anything at all about the class. The compiler doesn't know its methods. It doesn't know its superclass. All it knows is if it sees the token Foo, then that represents a class type. You can use this in header files so you can refer to the class in arguments and return types, but in order to actually do anything with values of that type you still need the full #import. But you can put that #import in the .m file without any problem.
The only time you need #import instead of #class in your header is if you want to inherit from the class in question. You cannot inherit from forward-declared classes, so you need the full #import. Of course, you may also need the #import if you need access to other types defined in the same header (e.g. structs, enums, etc.), but that's less common in obj-c.

How to define methods and properties only visible within an objective-c framework?

I am trying to write an objective-c framework and I would like to have methods and properties visible only within the framework. I know I could define them in a class extension inside the implementation file but then they will not be accessible by other classes.
One way I was thinking to do it was to define a category for example MyClass+Internals and make that header private. but make the MyClass.h header public. I was wondering if there was a better way of doing this. Also, I'm not sure you can define properties within a category I thought it was only methods. Thanks for any suggestions or feedback.
Say you have a class named "Foo", then in "Foo_Framework.h", create:
#interface Foo()
#property ....;
- .... method ....
#end
Then, make sure that "Foo_Framework.h" is imported before the #implementation Foo. That'll cause the class Foo to be compiled with the extended interface found in said header file. That header can then be used throughout your framework. Just don't make it available outside said framework.
You are correct that you can't declare properties (that are synthesized) in a category. That was one of the primary motivations for the creation of class extensions, of which the above is an example.

how to make methods in category classes available to other classes?

I want to use a class I got from iosframeworks.com called UIImage+ProportionalFill. I know it's a category extending UIImage, but when I try to use one of its methods in another class I get a message saying no visible #interface for UIImage declares the selector 'nameOfWhateverMethodIWantToUse'. I'm not surprised to get an error, since there must be more to using it than dropping it into XCode, but how do I make the methods in the new category/class available to other classes?
You just need to import your category in the class you like to use it...
#import "UIImage+ProportionalFill.h"
I usually do this in the header file.
The compiler needs to be able to see the declaration of the methods, which should be in the category's header file. You must import the header file wherever you want to use the methods.
You need to #import the header containing the method declaration(s) in each file that uses said methods.
Note tha the methos should be prefixed; i.e. -JDnameOfWhateverMethodIWantToUse.
Note also that adding categories to framework classes willy nilly can easily lead to a rather awfully architected application that becomes difficult to refactor/maintain.
Based on what you said, I think you just forgot to import it.
#import "UIImage+ProportionalFill.h"
Write it on the top of the .h file of the class where you want to use the method.

Is there a key combination in Xcode to implement a Protocol?

In Visual Studio if I define a class to implement an interface e.g.
class MyObject : ISerializable {}
I am able to right click on ISerializable, select "Implement Interface" from the context menu and see the appropriate methods appear in my class definition.
class MyObject : ISerializable {
#region ISerializable Members
public void GetObjectData(SerializationInfo info,
StreamingContext context)
{
throw new NotImplementedException();
}
#endregion
}
Is there anything anything like this functionality available in Xcode on the Mac? I would like to be able to automatically implement Protocols in this way. Maybe with the optional methods generated but commented out.
XCode currently does not support that kind of automation. But: an easy way to get your code bootstrapped with a protocol is to option-click the protocol name in your class declaration
#interface FooAppDelegate : NSObject <NSApplicationDelegate,
NSTableViewDelegate> {
to quickly open the .h file defining the protocol. From there, copy and paste the methods you're interested in. Those headers tend to be well-commented, which helps in determining which methods you can safely ignore.
I have not seen that feature in Xcode.
But it seems like someone could write a new user script called "Place Implementor Defs on Clipboard" that sits inside of Scripts > Code.
You did not find this useful.
There is not currently such a refactoring in Xcode.
If you'd like it, please file an enhancement request.
I know this thread s a bit old, but I wondered the same thing and found this question.
In my case, I'm defining a property in the interface (.h) and I want to synthesize it in the implementation (.m). I also need to implement methods defined in the interface. Yes, Xcode helps as others have mentioned, but modern IDEs offer these productivity enhancements for things we do frequently. It appears that this is still not a feature in Xcode 4.3.3. However, the feature is available in JetBrains' AppCode. I'm only dabbling with the trial, but it appears to only be possible one property or method at a time, not the whole interface like Visual Studio.
Xcode can help you per protocol method, lets say you have a protocol like this:
#protocol PosterousWebsitesDelegate <NSObject>
- (void)PosterousWebsitesLoadSuccess:(PosterousWebsites*)websites;
#end
in the #implementation section of your .m file you can start writing the name of the method and pressing ESC key to autocomplete the signature of the method/selector:
-(void)Poste (...press ESC...)
Xcode will autocomplete a full signature of the #protocol method, pres TAB to confirm the code.
If you are really committing to learn OSX/iOS Development, I would recommend you to read "XCode 3 Unleashed", a book that really helped me to know Xcode as deep as I know VS :)
check this plugin
https://github.com/music4kid/FastStub-Xcode
it does the thing that you are asking for and more.
Macrumors had a discussion on this too. There is a link to some apple scripts. I haven't actually tried these.