Import third party C library into swift causes error "Include of non-modular header inside framework module" - swift

This question is a continuation of a previous one I'm currently migrating this (https://github.com/emilwojtaszek/leveldb-swift) library from swift 2 to swift 3/4. Here is the link to my fork https://github.com/lu4/leveldb-swift/tree/MigrationFromSwift2ToSwift3 (please note that the target branch is MigrationFromSwift2ToSwift3)
I was able to resolve (with many thanks to #Ruslan Serebriakov) all of the issues with initial code base and check that the code is running.
However after trying to update LevelDB C code to latest master I got new type of error which I don't understand how to resolve:
Include of non-modular header inside framework module 'LevelDB.c': '/Path/to/Project/leveldb-swift-migration/vendor/leveldb/include/leveldb/export.h'
I've did some research on the internet but the issues described there seem non-related with one I've stumbled on. Here is an image of the issue
Any help is appreciated, thank you in advance!

I'm never 100% certain with mixed language frameworks. But an error like this happens in Swift projects when:
since you cannot use a Bridging Header in frameworks,
you #import a C header in the Foo-Framework.h to expose it so the Swift code, and
the header is not itself marked "Public" to the target.
"Non-modular" seems to indicate "not part of the published module interface". At least with Swift--C mixes, you can only combine both through making the C headers public; no way to import private header files there, which is weird.
Give it a shot: Since you are obviously importing the file in non-Swift code, try to locate the export.h header file in your Xcode project, open the File inspector (⌘⌥1), and ensure public visibility in the framework target:

This issue is because the SDK u are importing is not modular or u can say modulemap file is missing. So make sure modulemap file should be available inside the framework folder. Also make sure that all public headers are listed explicitly in the modulemap. This issue will be resolve 100% if module map file will be include in the third party framework.

Related

Using static C library in swift, cannot find module

I need to create a swift wrapper for a C library for use on both iOS and macOS.
I have added the .a to the frameworks list and include it in library search path. I have added the header file to project and added it to User header search paths and I have added a module.modulemap to the project as well. Looking like this:
module codinglibc [system][extern_c] {
header “codinglibc.h”
export *
}
But when I import the module in Swift:
import Foundation
import codinglibc
I get this error message: No such module 'codinglibc'.
The project is a Cocoa Framework and I have been following this guide: https://medium.com/swift-and-ios-writing/using-a-c-library-inside-a-swift-framework-d041d7b701d9
I have looked at a lot of stackoverflow answers but most have been solved by adding import paths, which I already have done and Xcode can find both the header file and the static library so that is not the issue.
So:
1. Have I done something obviously wrong which I have missed?
2. Should I use briding headers instead?
Edit: I tried enabling Allow Non-modular Includes In Framework Modules
still no success
The answer is pretty trivial, yet annoying.
If you add the module.modulemap in an Xcode project, Xcode will not register it as "to be imported", so what you need to do is to add the path to you module.modulemap file in the header includes.

How to make a Swift framework submodule really private?

I've found another question which brings more details regarding the problem and possible solutions. It seems like there is a known bug which is a subject for future improvements.
Objective C classes within an iOS Swift-based dynamic framework
I'm developing a framework in Swift and I'm using some Objective-C code inside the framework. So far my module map looks like this:
framework module MyModule {
umbrella header "MyModule-umbrella.h"
export *
explicit module Private {
header "MyTools.h"
}
}
My concern is that all the APIs from MyTools.h are visible from outside the framework: for example, if you install the framework using Cocoapods, then you import MyModule into your application (not MyModule.Private), you are able to access MyTools.h which is not desirable and redundant. Is there any way to make MyTools invisible from outside the framework?
PS. I use Cocoapods to distribute the framework, here is my podspec (the most significant part):
s.module_map = 'Pod/MyModule.modulemap'
s.frameworks = 'CoreData', 'CoreTelephony', 'SystemConfiguration'
s.resources = 'Pod/Classes/MessageStorage/*.xcdatamodeld'
s.public_header_files = 'Pod/Classes/**/*.h'
s.private_header_files = 'Pod/Classes/MyTools/**/*.h'
s.source_files = 'Pod/Classes/**/*.{h,m,swift}'
PSS. My umbrella header does not import MyTools.h
PSSS. Just tried to exclude the header from the main module:
framework module MyModule {
umbrella header "MyModule-umbrella.h"
export *
exclude header "MyTools.h"
explicit module Private {
header "MyTools.h"
}
}
No luck.
I found another question which brings more details regarding the problem and possible solutions (which don't work though). It seems like there is a known bug which is a subject for future improvements.
Objective C classes within an iOS Swift-based dynamic framework
I had exactly the same problems recently. The quick answer is you can't :) Even if you declare "private" modulemap, it can be always imported by your framework users. Please note, that usually, it is not a concern, especially with open source. You just say "this is an internal module, don't use it".
But (there is always but) - you can have behavior, that effectively works the same - allows you to use your Objective-C classes withing same framework target, without making them public. It works in closed source setup, I'm not 100% sure how would it behave with pods.
The case a bit too complex to paste everything here. I'm adding a link to my article about the topic, maybe it will help you. But speaking honestly - it might be a bit of overhead in your setup.
Creating Swift framework with private Objective-C members. The Good, the Bad, and the Ugly
Github example project

Use of unresolved identifier 'PFQuery'

So I am following this tutorial https://www.youtube.com/watch?v=Q6qcrO8uNzU&feature=youtu.be for Parse and when defining a PFQuery variable I get this error: "Use of unresolved identifier 'PFQuery'".
Code Below:
var getMessages = PFQuery(className:"DevelopmentMessages")
How would this be fixed? Thanks in Advance! ;)
You haven't included the Parse framework in your project correctly. This is done about 7 minutes in during Part 1 of that tutorial: http://www.youtube.com/watch?v=Q6kTw_cK3zY
It is also covered in Parse's QuickStart instructions:
https://parse.com/apps/quickstart#parse_data/mobile/ios/native/existing
All you need to do is the "Install the SDK" portion but you also need to include the Parse framework's header in your Objective-C bridging header:
#import <Parse/Parse.h>
The problem might be because you might not have imported the libraries properly. Drag drop the library files into the project properly. Make sure you have added the library inside your project folder and not outside it. Sometimes it may also be the cause of the problem.
Note - Please don't forget to check the option "Copy files if needed" while dragging and dropping the library files.
Update - If you have named your project as "parse" then it will not work. So rename your project to any other name and try it.

Compiler error when using AlwaysRightInstitute/SwiftSockets

I'm try to write a small game on IOS using socket and I've had a java socket server running with Flash client, but I got complier errors when I add the AlwaysRightInstitute/SwiftSockets source code to my swift project, and I did nothing after doing this
Here is the project structure:
the selected group "ARISockets" is the source code I drag into my project
and here are the errors(Use of unresolved identifier 'ari_fcntIVi'):
It seems that the errors cause by lack of some import file and I found "ari_fcntIVi" in ARISockets/UnixBridge.c,but I'm a really newer to Swift/Objective-C/C (I'm a AS3 developer), so that sucks me :/
I had the same problem with this library.
You need to create a Bridge file similar to "Import Objective-C into Swift" but this is C:
How to call Objective-C code from Swift
The issue was that you just copied over the sources instead of embedding the SwiftSockets framework. The ari_ prefixed functions used to required the bridging header of the SwiftSockets framework.
Having said that, the current SwiftSockets doesn't use bridging headers anymore, and you can directly embed the sources.

unable to create new static Library out of existing source code

I'v done quite a bit of R&D on creating static libraries in iOS and came across some well written blogs. I followed this link and also this to create a static library. I have follwed the steps specified in those blogs i.e, i added all the implementation files(.m) to the static library and deleted them from the main target etc... But, i am getting around 700 erros (which is quite bizarre) when i try to build the code. i am posting a screenshot of my errors here..
Is there anything that i am missing here or doing wrong?
Please check the imported Header files.
The .m files, which have these errors, may have the same imported files.
Maybe a semi-comma or parentheses is missing or used incorrectly.