Bridging-header works, but imports are not working? - ios

I installed a library using CocoaPods, and it all seems to work. I added a bridging-header to my project, which I know works since I use several different libraries in this header. But I just installed and bridged libPhoneNumber-iOS and it seems to work, except...it doesn't. I find the files, it imports them correctly in the header, but I can't use it in swift. It should be NBPhoneNumberUtil, but it doesn't exist.
I have imported them like this in my header:
#import "libPhoneNumber_iOS/NBPhoneNumberUtil.h"
#import "libPhoneNumber_iOS/NBPhoneNumber.h"
and if I type anything differently it will give me an error saying it can't the specified files, so this should be imported correctly. Also if I type NBPhoneNumberUtil in this header-file I can see the object so it works. But in my swift-project the modules doesn't exist. Again, I know my bridging-file works since I use other libraries in this file, and in swift. Any ideas what might be wrong?
Update #1:
So I tried adding import to my swift-file, and it "works".
import libPhoneNumber_iOS/NBPhoneNumberUtil
import libPhoneNumber_iOS/NBPhoneNumber
Except that Xcode complains that this is not a viable syntax, it wants to add a semi colon somewhere. But now I can create the objects I need, but I can't compile since Xcode wants me to fix the errors first. This is so weird. Any ideas?

I resolved the issue now. The issue was that I use use_frameworks! in my pod file so the paths are different. In fact, when you use use_frameworks! you don't need a bridging header, and have to import the files directly in swift. The problem was that I didn't know how to import it, but now I do.
pod file:
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
platform :ios, '8.0'
target 'test' do
pod 'libPhoneNumber-iOS', '~> 0.8'
end
target 'testTests' do
end
In the Xcode project you do not need a bridging header anymore, and simply import the library where you want to use it, like this:
import libPhoneNumber_iOS
Now it should be working. Hope this helps someone else.

The answer is to import them like this in your bridging header:
#import "NBPhoneNumberUtil.h"
#import "NBPhoneNumber.h"
The procedure that I used to test this is written below.
Create a new Xcode project
I used the Single View Application template for Objective-C.
Create Podfile and Install
Podfile:
source 'https://github.com/CocoaPods/Specs.git'
pod 'libPhoneNumber-iOS', '~> 0.8'
Install:
$ pod install
Create a Swift file
At this point a bridging header file was created by Xcode.
I added the imports into the bridging header using:
#import "NBPhoneNumberUtil.h"
#import "NBPhoneNumber.h"
In the Swift file, I wrote:
class Test {
func test() {
let util = NBPhoneNumberUtil()
}
}
The project compiled without errors.

Related

How to use FCUUID in a Swift project? [duplicate]

Is there a way I can use a CocoaPod written in Objective-C in my Swift project using swift?
Do I just make a bridging header? And if so, can I access the objects, classes, and fields defined by the libraries in the CocoaPod in Swift?
Basic answer to your question is Yes, you can use objective-c code built with CocoaPods.
More important question is "How to use such libs?"
Answer on this question depends on use_frameworks! flag in your Podfile:
Let's imagine that you want use Objective-C pod with name CoolObjectiveCLib.
If your pod file uses use_frameworks! flag:
// Podfile
use_frameworks!
pod 'CoolObjectiveCLib'
Then you don't need add any bridge header files.
Everything that you need is import framework in Swift source file:
// MyClass.swift
import CoolObjectiveCLib
Now you can use all classes that are presented in lib.
If your pod file doesn't use use_frameworks! flag:
// Podfile
pod 'CoolObjectiveCLib'
Then you need create bridging header file and import there all necessary Objective-C headers:
// MyApp-Bridging-Header
#import "CoolObjectiveCLib.h"
Now you can use all classes that are defined in imported headers.
In podFile use the flag use_frameworks!
Inside Xcode in the Pod folder structure in the dependency, you add xxxxxxx-umbrella.h in Support Files.
In your {PROJECT_NAME}-Bridging-Header.h use:
#import "xxxxxxx/xxxxxxx-umbrella.h"
It works for me.
You just need a bridging header and import there what you need.
AND don't forget to add Bridging Header file name to Target -> Build Settings -> Objective-C Bridging Header

When trying to use cocoapods with swift getting error: bridging header does not exist?

I'm trying to use this ExpandingTableView pod. When I tried to use it in my project Expense, it didn't work, so I looked at this Stackoverflow post and followed the linked tutorial. Except now I'm getting an error:
error: bridging header '/Users/Monica/Documents/CS 4999/Project/Expense/Expense/Expense-Bridging-Header.h' does not exist
As part of the tutorial, you are suppose to go into your project's Build Settings and edit the key Objective-C Bridging Header to project_name/project_name-Bridging-Header.h (in my case: Expense/Expense-Bridging-Header.h). And that's what I did as you can see.
In attempt to fix this error, I edited the key Objective-C Bridging Header from Expense/Expense-Bridging-Header.h to Expense/Header.h, Expense-Bridging-Header.h, Bridging.h, ./Expense/Bridging.h, or ./Expense/Expense-Bridging-Header.h. Nothing solved the error.
If anyone could tell me why this is happening & how to fix this—it would be greatly appreciated!
This is how the files in my project Expense are arranged in Xcode.
These are the files of ExpandingTableView pod in Xcode.
This is where Bridging.h is located on my computer.
My podfile:
# Uncomment this line to define a global platform for your project
platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!
target 'Expense' do
pod 'ExpandingTableView'
end
target 'ExpenseTests' do
end
target 'ExpenseUITests' do
end
If you're using frameworks, then you no longer need a bridging header. Instead, you will import the framework directly in the swift file in which you will be using it like so:
import ExpandingTableView
class MyTableView: UITableViewController{}

CocoaPods not building target for Crittercism

I added pod 'CrittercismSDK' to my Podfile and ran pod install, it finished with no error, all good.
Using import Crittercism gives No such module error. I looked into the Pods/ directory, there source code is there; however, the Pods project doesn't have a target called Pods-MyProject-Crittercism (but it does have targets for each dependency).
Build keeps failing because the import isn't found. What am I doing wrong?
PS: I'm using use_frameworks! directive in my Podfile, and I have another obj-c library that works fine, so I don't know why this one isn't working.
While this is not a general answer, I have found that:
Not using #use_frameworks
Using a Bridging-Header.h containing #import "Crittercism.h"
Not importing CrittercismSDK in the Swift class, but merely executing Crittercism.enableWithAppID("appId") does the trick.
See if below steps helps in your case. What version of pod/Xcode in use? It will be great if you can share your pod file, thanks.
Install dependencies using Cocoapods and the use_frameworks! flag.
As you need to use a Objective-C dependency, create a Bridging header. You can create one easily by importing an Objective-C class to your Swift project, than remove it (the wizard should ask you if need a bridging header). Otherwise, create a new header file. Then, navigate to your target configuration and enter the name of your file in Swift Compiler - Code Generation > Objective-C Bridging header.
Still in your target configuration, add a new entry in Search Paths > User Header Search Paths: Pods as value and flag it as recursive.
Remove any import instruction from your code, relative to your Objective-C library.
Build your project. You should have a success.

Xcode can't see objects added via Cocoapods

I have a podfile defined with the following pods.
platform :ios, '8.0'
use_frameworks!
target 'LifeStream' do
pod 'SSKeychain'
pod 'LiveSDK'
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'swift-2.0'
end
I installed the pods and opened up my workspace. I have found that any usage of Alamofire works fine, due to the Swift 2 version of it importing the project as a framework.
When I try to use SSKeychain classes however, I receive a
Use of unresolved identifier 'SSKeychain`
Same applies with any class I try to use in the LiveSDK.
I have a bridge header in my projects root directory, and the project is configured to use it.
#ifndef Header_h
#define Header_h
#import "SSKeychain/SSKeychain.h"
#import "LiveSDK/LiveConnectClient.h"
#endif /* Header_h */
if I change the #import from
#import "SSKeychain/SSKeychain.h"
to
#import "SSKeychain.h"
Xcode fails to compile because it can't find the file. So I assume that the bridge header is working, as the way my bridge header is built now does not generate any compiler errors caused by not finding the headers.
Bridge Header
Framework Search Paths
I have also added my project root directory to the framework search path.
Linked Frameworks
Lastly I have linked all of the frameworks to the project as well.
Am I missing something with my setup? I have not been able to get Cocoapods to work on my project for nearly a week now. I even created a brand new project thinking that mine was just messed up; which didn't change a thing. I don't know what to do from here in order to resolve this.
Edit
After doing some additional research, I found a blog post showing that you have to include your Pods directory in the User Header Search
A commenter also mentioned that if you are using the newer Cocoapods Frameworks support for Swift, then it will need to include the Frameworks/** search path. I've included both Pods/** and Frameworks/** but still have the same issue.
After some further reading, it's beginning to sound like this is a limitation of Cocoapods. From what I understand, you can't use libraries and frameworks together at the same time in a project.
Once you use use_frameworks! in your Podfile, Objective-C Pods like SSKeychain also get build as frameworks.
The actual problem is that only module imports work in the bridging header when using frameworks. Also, you might want to get rid of the bridging header entirely, as it is unnecessary when using frameworks, they can be imported directly in Swift.
To clarify what you should do to make it work:
Be sure to have use_frameworks! in your Podfile
It doesn't matter if you have a Bridging header or not. Leave it untouched
In your SWIFT file just use import Podname
That's it, you're good to go. Of course it may happen that you need to clean your project or maybe delete the derived data folder. Build and you can use it.
If you're not using any swift pods,
Try removing the use_frameworks! on your Podfile.
Run pod install on terminal.
Clean & Build !
I spent almost half an hour fixing it, I tried adding those paths on Search Paths or re-adding the bridging-header but the error was the same.
Therefore, in my case, bridging header file was not the problem, its on the Podfile .
I hope it helps!

Adding SocketRocket to a Swift project through Pods

I'm trying to add the SocketRocket framework to my Swift project using pods and I haven't been able to get the import to work on the Swift side.
I added the following entry to the Podfile:
pod 'SocketRocket', '0.2.0'
And ran pod install.
Then added the bridging header with:
#import <ScoketRocket/SRWebSocket.h>
In my ViewController, Xcode doesn't find the header file:
import SRWebSocket
fails. I really hope to get this done through pods instead of manually adding the files to the project.
Thanks.
Is there a typo ?
#import <ScoketRocket/SRWebSocket.h>
ScoketRocket/SRWebSocket.h
You have to import modules by their module name and not their header name:
import SocketRocket
If you use that in your view controller, then you wouldn't even need an import in the bridging header. Module Imports work with CocoaPods since >= 0.36 with frameworks support, which you have explicitly enable by putting the following in your Podfile:
use_frameworks!
You can still use SocketRocket with older versions of CocoaPods and without this directive from Swift, by adding the import statement to the bridging header like you already figured out. If you do that, you don't need a further import statement in your view controller. The bridging header makes imports available for the whole Swift module.

Resources