I started a "Cocoa Touch Static Project" with a Cocoa Pods dependance.
Podfile:
platform :ios, '8.4'
inhibit_all_warnings!
target 'project' do
pod 'libPusher', '~> 1.6'
end
target 'project' do
end
A workspace has been created by the command "pod install".
Then I created un swift project on this workspace and I created a Bridge header between this swift project and my Objective-C library project.
My swift project configuration:
//:configuration = Debug
SWIFT_OBJC_BRIDGING_HEADER = demo/demo-Bridging-Header.h
//:configuration = Release
SWIFT_OBJC_BRIDGING_HEADER = demo/demo-Bridging-Header.h
When I compile my swift project, I obtain this error:
demo-Bridging-Header.h:5:9: In file included from /Users/XYZ/Projets/iOS/project/library/demo/demo/demo-Bridging-Header.h:5:
project.h:10:9: 'Pusher/PTPusherDelegate.h' file not found
Failed to import bridging header '/Users/XYZ/Projets/iOS/project/project/demo/demo/demo-Bridging-Header.h'
Do you know why the swift compiler doesn't found header file and how can I fix it?
• Did you run pod install ?
Installing SocketRocket (0.3.1-beta2)
Installing libPusher (1.6)
• Did you open demo.xcworkspace (close Xcode project, open Xcode workspace)
If so, were is the correct demo-Bridging-Header.h content:
#import "Pusher.h"
#import "Pusher/PTPusherDelegate.h"
Related
Is there any possibility to use MapboxNavigation (version 0.21 or 0.22) iOS with Xcode 10. On its Github and CocoaPods site is stated, that it can only be used with Xcode 9, but a few issues on Github mention the (successful) use of Xcode 10 with MapboxNavigation.
However, I tried to install MapboxNavigation via CocoaPods using Xcode 10 and get a bunch of errors:
/Users/Paul_Obernolte/Library/Developer/Xcode/DerivedData/pq-app-v2-gynuaxsohvqddqegrvemywowchkr/Build/Products/Debug-iphonesimulator/MapboxDirections.swift/Swift Compatibility Header/MapboxDirections-Swift.h:171:9: error: 'MapboxDirections/MapboxDirections.h' file not found
#import <MapboxDirections/MapboxDirections.h>
^
<unknown>:0: error: could not build Objective-C module 'MapboxDirections'
Is there any workaround to avoid this errors using Xcode 10?
Edit: Here is my Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
EXPO_CPP_HEADER_DIR = 'ExpoKit'
target 'pq-app-v2' do
pod 'MapboxDirections.swift', '~> 0.23'
pod 'MapboxMobileEvents',
:git => 'https://github.com/mapbox/mapbox-events-ios.git',
:commit => "79d29f1df5a9187481f5c9ac8fa13430d1f04139"
pod 'MapboxNavigation', '~> 0.21.0'
... (more Pods)
end
I need to download MapboxMobileEvents separately because of this issue: https://github.com/mapbox/mapbox-events-ios/pull/85
target 'pq-app-v2' do
use_frameworks!
... (more Pods)
end
change code in pod file if "use_frameworks!" is commented than put it uncommented as above.
I am using Fabric and I had no issues before, until I added a new Target, which is required for a "Today Extension".
"Multiple Targets" of type "Today Extension"
I have added a "Run" script build phase to this newly created target with the same parameters as the "Main Target", as well as the the Fabric keys in the Info.plist for both targets.
Run Script: "${PODS_ROOT}/Fabric/run" hex_value.... hex_value...
When I build the project I am getting build errors that states:
fatal error: 'Crashlytics/Crashlytics.h' file not found
My import statement is this, and is in a file that is shared
and selected to be for both targets (Target membership).
#import <Crashlytics/Crashlytics.h>
The Fabric run script is part of the build script and should be added to each target and should be the last item in the build phases list.
e.g. Add the run script to the "Today Extension" target.
(note: it is not needed to add the Fabric details to the plist file for the "Today Extension" target).
The header file that is not found is related to the "Search Paths",
and if the Fabric is installed via CocoaPods.
Make sure the Podfile installs it for both targets.
Run a "pod install" command after editing the Podfile.
Note: the two targets both include Fabric.
e.g.
platform :ios, '9.0'
# Uncomment this line if you're using Swift
# use_frameworks!
use_frameworks!
target 'MyApp' do
pod 'Fabric'
pod 'Crashlytics', '~> 3.9'
end
target 'MoTodayExtenstion' do
pod 'Fabric'
pod 'Crashlytics', '~> 3.9'
end
post_install do |installer|
puts("Update debug pod settings to speed up build time")
Dir.glob(File.join("Pods", "**", "Pods*{debug,Private}.xcconfig")).each do |file|
File.open(file, 'a') { |f| f.puts "\nDEBUG_INFORMATION_FORMAT = dwarf" }
end
Note the post_install part in the Podfile, this step
updates/creates the xcconfig file that resides in the Xcode.
Look in the "Pods" folder within the Xcode application Project;
Inside these files are a couple of variables
FRAMEWORK_SEARCH_PATHS
GCC_PREPROCESSOR_DEFINITIONS
HEADER_SEARCH_PATHS
LD_RUNPATH_SEARCH_PATHS
OTHER_CFLAGS
OTHER_LDFLAGS
PODS_BUILD_DIR
etc....
Specifically the "HEADER_SEARCH_PATHS" should include the path the
header file that could not be found.
The Setup
I have successfully integrated the GoogleMaps SDK into my Swift 2 project using CocoaPods.
My setup is pretty much that suggested by the Ray Wenderlich tutorial on the subject.
The only difference I can find is, I have to add this line to AppDelegate:
import UIKit
import GoogleMaps // <- THIS LINE
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
...
...in order to use the framework's classes. The tutorial suggests importing:
#import <GoogleMaps/GoogleMaps.h>
...to the bridging header instead.
The app works without problems.
The Problem:
When I tried to run the test target auto-generated by Xcode, I get the error:
No such module 'GoogleMaps'
...pointing at the to the swift import statement in AppDelegate above.
So, I decide to switch to the way it is in the tutorial instead: I comment out the line import GoogleMaps in AppDelegate.swift and add an Objective-C-style import statement to the bridging header.
However, I can not get it right:
If I use: #import <GoogleMaps/GoogleMaps.h> or #import "GoogleMaps/GoogleMaps.h", it gives me:
Use of unresolved identifier 'GMServices'
at AppDelegate.swift when building the app target.
If I use: #import "GoogleMaps.h", it gives me:
'GoogleMaps.h': file not found
at the bridging header.
I have tried the solution in this answer, but the results are (puzzlingly) the same...?
Next, I checked the value of Build Settings / Search Paths / Framework Search Paths for both targets (app and tests). The app target had the entry:
"${PODS_ROOT}/GoogleMaps/Frameworks"
...which the test target lacked, so I added it, and reverted to the swift-style import (the only one that works at least when building the app target), but I still get:
import GoogleMaps <! No such module 'GoogleMaps'
How can I run tests for my app??
So, it turns out all I had to do is fix the Podfile (and run pod install), as explained in this answer.
My old pod file:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.1'
def import_pods
pod 'GoogleMaps'
end
workspace 'MyWorkspace'
xcodeproj 'MyApp/MyApp.xcodeproj'
target : MyApp do
xcodeproj 'MyApp MyApp.xcodeproj'
pod 'GoogleMaps'
end
My current pod file:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.1'
def import_pods
pod 'GoogleMaps'
end
workspace 'MyWorkspace'
xcodeproj 'MyApp/MyApp.xcodeproj'
target 'MyApp', :exclusive => true do
xcodeproj 'MyApp/MyApp.xcodeproj'
import_pods
end
target 'MyAppTests', :exclusive => true do
xcodeproj 'MyApp/MyApp.xcodeproj'
import_pods
end
I created an objective-c pod with two files:
Source/SomeViewController.h
Source/SomeViewController.m
I also created a bridging header in the pod:
Source/Bridging-Header.h
with the content:
#import "SomeViewController.h"
My podspec looks like this:
Pod::Spec.new do |s|
s.name = 'TestLib'
s.version = '0.0.1'
s.license = 'MIT'
s.ios.deployment_target = '7.0'
s.source_files = 'Source/*.{h,m}'
s.requires_arc = true
s.xcconfig = { 'SWIFT_OBJC_BRIDGING_HEADER' => 'Source/Bridging-Header.h' }
end
I created a demo project did pod init and inserted my pod. Then after pod install I get the following output:
Installing TestLib 0.0.1 (was 0.0.1)
Generating Pods project
Integrating client project
[!] The `TestLibProject [Debug]` target overrides the `SWIFT_OBJC_BRIDGING_HEADER` build setting defined in `Pods/Target Support Files/Pods-TestLibProject/Pods-TestLibProject.debug.xcconfig'. This can lead to problems with the CocoaPods installation
- Use the `$(inherited)` flag, or
- Remove the build settings from the target.
[!] The `TestLibProject [Release]` target overrides the `SWIFT_OBJC_BRIDGING_HEADER` build setting defined in `Pods/Target Support Files/Pods-TestLibProject/Pods-TestLibProject.release.xcconfig'. This can lead to problems with the CocoaPods installation
- Use the `$(inherited)` flag, or
- Remove the build settings from the target.
When I open my TestLibProject.xcworkspace file I see that the pod was installed correctly but the bridging header from the pod is not installed correctly. I my Swift project I tried to do:
let vc: SomeViewController
This gives an error because the bridging header from the pod ist not installed.
How do I have to configure the podspec in order to get the bridging header of the pod being installed correctly?
Podspecs build frameworks, and frameworks cannot include bridging headers. If you want to import non-modular code into a Swift framework, you'll need to use a custom module map, instead, e.g. at MyLib/module.modulemap:
framework module MyLib {
umbrella header "MyLib.h"
// Load an SDK header, e.g. CommonCrypto.h
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
module * { export * }
}
Once there, you can specify the custom module map both in your Xcode project (either as the MODULEMAP_FILE setting in an .xcconfig file, or as the Module Map File of your target's Build Settings.
Now, the final piece of the puzzle: the podspec. You need to set the module_map:
Pod::Spec.new do |s|
# …
s.module_map = 'MyLib/module.modulemap'
end
The above is how SQLite.swift distributes itself, both as a general framework and as a pod.
Edit: Seems like I missed the point of the original question, as was clarified in this thread. The OP wanted to use a pod framework's bridging header to automatically load itself into the installing project's Swift code. This isn't possible. Even if Swift frameworks did support bridging headers, they would only be able to load Objective-C/C code (i.e. private framework code) into the framework's Swift code.
I am trying to create a swift module (Cocoa Touch Framework) with reusable code inside the environment set up by cocoa pods which includes third party libraries written in Objective-C (namely here Restkit).
Unfortunately I am not able to use Restkit in the module I create.
Here's what I did to create the module:
File -> New target: Cocoa Touch Framework, Language: Swift, Project: MyProject, Embed in Application: MyProject
In the "Info" tab of the project settings in the "Configurations" section I define the Pods.debug and Pods.release xcconfig file for my newly created target.
In the header file, which Xcode automatically created for me, networkModule.h, I add the following line:
#import <RestKit/RestKit.h>
Result: When trying to compile I get the error "include of non-modular header inside framework module 'networkModule'"
I have set the flag for "Allow Non-modular Includes in Framework Modules" to YES in the build settings for the Project Target and the Module/Framework target.
I went to the Cocoa pod project and have tried setting the visibility of the RestKit.h Header file to "Public" in the target membership (which of course is not a good solution to mess with the cocoa pods environment)
I am not able to compile. I still get the same error.
Is it possible in the first place to create a Cocoa Touch Framework with dependencies to a cocoa pod managed framework?
Btw. My first idea of creating a private cocoa pod didn't work out as well, as it doesn't seem to be supported, although I am using the prerelease of cocoa pods 0.36 with support for swift.
You should be able to make your won private Pod. You just need to make a podspec for it. Here is an example of one.
Pod::Spec.new do |s|
s.name = "Commons"
s.version = "1.0.0"
s.summary = "Common code for my iOS projects."
s.license = {:type => 'Commercial', :text => "Copyright (c) Dan Leonard(Or Your Name?). All rights reserved." }
s.source = { :git => "https://github.com/PATHTOPOD", :tag =>
s.version.to_s }
s.homepage = "https://github.com/PATHTOPOD"
s.requires_arc = true
s.ios.deployment_target = '9.0'
s.subspec 'Core' do |ss|
ss.source_files = '*.swift'
end
s.subspec 'Menu' do |ss|
ss.source_files = 'Menu/*.swift'
ss.resources = ['Menu/*.storyboard', 'Menu/*.xcassets']
ss.dependency 'Alamofire'
end
end
Then Inside your project you just have to do pod init open your podfile that was just created and add this
source 'https://github.com/CocoaPods/Specs.git'
xcodeproj 'YOURPROJECT.xcodeproj'
platform :ios, '9.0'
use_frameworks!
pod 'Commons', git: 'https://github.com/PATHTOPODPROJECT'
#pod 'Commons', :path => '/Users/YourUser/Path/To/Project/commons'
pod 'KeychainSwift'
pod 'SQLite.swift', git: 'https://github.com/stephencelis/SQLite.swift.git'
Now in this example Podfile Commons is stated twice the second is commented out. If you uncomment it and comment out the first then do pod install in your projects folder from the terminal. This will make a DevelopmentPod which is a pod that is local. This way you can make changes to the pod locally within Xcode. No switching and pod installing every time you make a change.
You will import the pod just like any other by putting
import Commons not #import <Commons/Commons.h> That is how you do it in Objective C not Swift
Once you have a working version commit it to git hub and point your project to the the github version.
Hope this helps.