I am confused when working with Xamarin obj-c bindings, Lets say if I am having a single .h file then its just an happy path when creating binding. But when a .h file is referenced with another .h in it as an import statement. How to deal with the bindings.
If I am having AB.h file which has A.h referred in it, what is the way to generate bindings for this. And If I am having a .xib file in obj-c project then how to deal with that.
Example Sake I am using this project for conversion.
https://github.com/hightower/HTHorizontalSelectionList/tree/master/Source
Have you looked at the Objective Sharpie, it will automatically identify the dependency and help you get started with creating iOS bindings
Related
My project is in Swift and I integrated a third party library for a feature which was all hard coded in Objective-C. Now I want to access my swift files from the Objectiv-C code for smooth navigation and data accessibility.
I tried everything mentioned [here], and a file like -Swift.h is generated under Objective C generated header name.
But no file is created under Derive Data folder.
I can't share the code as it is not allowed on my part, but when I import the file as #import "-Swift.h", it shows "No file Found".
I added forward declaration too. But of no use. Please help with this.
1:
I have an old Objective-C project, which has multiple targets, and some of the targets share a framework (let's call it CJDataKit) that's also written in Objective-C. I'm trying to add some Swift code to my project, at least to the main app target, and have some limited implementation of it working, but I'm running into some issues whenever the Swift code needs to use or import the CJDataKit framework, or any header file that itself imports the CJDataKit framework.
What's Working
I wrote a basic UIView subclass in Swift (which didn't need any other code from my app), and I can use this in my Objective-C target, using #objc keyword and by importing "MyApp-Swift.h" in my Objective-C code.
I then wrote a new UIViewController subclass in Swift, and used a couple of simple Objective-C objects from both CJDataKit framework and non-framework classes. I did this by creating a bridging header file, and added the Objective-C headers there.
So far so good, and everything compiles fine.
What's Not Working
The problem happens if I try to import into Swift other Objective-C
files that might be importing the CJDataKit framework inside it. For
e.g. I wanted to write a Swift extension of an existing
UIViewController subclass (call is PageAViewController). This
subclass has imported multiple other header files. If I add it to the
bridging header file, I start getting build errors:
Include of non-modular header inside framework module 'CJDataKit':
'.../CJDataKit/Person.h'
Commenting out the #import CJDataKit makes it work for this particular file, but it still gets compile errors from a different header file (that was imported by PageAViewController). It'll only work if all the files imported don't have a #import CJDataKit, which is difficult and cumbersome. BTW, these files all belong to the app target, not the framework. So something about Swift doesn't like interacting with the CJDataKit framework directly, even though it works fine if it's built independently in the same app target along with the CJDataKit framework.
I've also tried importing the CJDataKit.h header file into the Swift
bridging header file, figuring this way I don't have to individually
import each file from the framework, but that doesn't work either.
That results in a different error:
Could not build module 'CJDataKit.h'
I've tried using #import <CJDataKit/CJDataKit.h> as well but same result.
From my settings:
- "Allow Non-modular Includes In Framework Modules" is Yes on the target, and framework. It is No at the project-level.
- "Defines Module" is also set to Yes, on both the app target and framework, and No at project-level.
Would love some help in getting this setup correctly. I've been searching for a solution, but haven't really found anything.
In my Swift Project, I added a new cocoa Objective-C class (UIViewController), Xcode prompted me whether I want it to automatically generate an Objective-C bridging header file.
I am a bit confused because the generated file is ProductModuleName-Bridging-Header.h while, as per Apple documentation, I was waiting to get a ProductModuleName-Swift.h instead (In order to import Swift into Objective-C).
The ProductModuleName-Bridging-Header.h is mandatory in order to be able to import Objective-C from Swift, and not the inverse.
Any clarification on this?
Thanks
The behavior you describe is exactly correct. You're adding Obj-C to your Swift project, therefore Xcode offers to create a -Bridging-Header.h file which allows that imported Obj-C to be used in your Swift code. This is described in the documentation you linked under "Importing Objective-C into Swift".
Unlike the bridging header, the -Swift.h file doesn't appear in your file hierachy, and is not something you see or edit. It's generated and managed entirely by Xcode during the build process. You simply import into .m files when needed.
I have an objective-c class that uses swift classes. It all works fine.
I wanted to import the objective-c class into a swift class, so I added its header file to the bridging header. All the sudden I got an error the Projectname_swift.h file is not found.
Any ideas how to resolve this issue?
Is it actually possible?
a circular reference has been created, making it so the Swift code is unable to compile (which leads to the canary error stating that the _Swift.h file is not found).
i have provided a more in depth answer to a similar questions here and here.
long story short, the documentation explicitly says not to this:
To avoid cyclical references, don’t import Swift code into an Objective-C header (.h) file. Instead, you can forward declare a Swift class or protocol to reference it in an Objective-C interface.
Forward declarations of Swift classes and protocols can only be used as types for method and property declarations.
in order to make your code compile again you will need to remove the #import "Projectname_Swift.h" line from the offending Objective-C header. ideally you can simply move the import statement into your .m file, however if you need to publicly expose the Swift class in your ObjC header, then you must forward declare it using #class SomeSwiftClass;.
Let the Xcode build the bridge file from Objective-C to Swift.
Create a temporary directory elsewhere. In there, you create a dummy Xcode Swift project, give the project name the same as your existing Current Project Name.
Then add new file, Objective-C (.m file). The XCode will prompt you to create a bridge header file, click on the create bridge file (the right most button).
Now you locate the header file location in Finder. Then drag into your Current Project of Interest, don't forget to checked the copy file if necessary option. Add necessary #import '.....' in the header file.
You should be good. If everything works fine, delete the dummy project.
Clean derived data. and then #import "ProjectName-Swift.h" in your objective c files.
Go to
Build Settings->Objective-C Generated Interface Header Name
and set the value to YourModule-Swift.h (this is usually already set, this is the filename you need to import on .m file #import "YourModule-Swift.h"
Go to Build Settings and search for "Defines Module", set both values to YES
Create a class in swift with prefix of #objc for example
#objc class mySwiftClass{...}
Build the project again
it will be better if you use error syntax or screen shot. you can simply try this
1. Goto your project on top of right navigation
2. select build settings from middle pain.
3. search for Objective-C bridging header
4. just below this you will find "Generated interface HeaderName"
5. add correct address of your swift file
6. clean and build the project.
Every so often I'll start a little 'helper class' and find that I can cover my needs entirely with C functions (although these functions may often have ObjC within them, maybe return type or some args of NSDictionary* or whatever..), and so i'll delete the #implementation and #interface and there is no class there at all, just .h and .m files..
What is the best practice, ought I change my .m file to a .c file? Or is this impossible/difficult with ObjectiveC types in there? Is there any benefit to using a different file type that I'm unaware of or is what I'm doing just fine? (I only develop for OsX and iOS, and entirely with xCode, at least for now.)
thanks for your time :)
When you make a Command Line tool using Xcode it gives you a .m file for your code despite the fact that the initial file is not a class implementation file, so it may be best to follow this pattern (this is also true for the main file in other projects).
If you select a file in Xcode and have the right hand bar open you can let Xcode know how to parse that file. So if you've got ObjectiveC in your .c file you can change the Parse type from a C file to an ObjC file and it will all work correctly.