Using Cocoapods in an app extension using a framework
So, what gives :
- My concern of "separating pods between targets" is absurd because you can still import them anywhere.
- The "you have to manually link" issue is fixed by an easy
import RealmSwift
statement.
The fixed and working Podfile therefore is :
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'Eureka', '~> 2.0.0-beta'
pod 'PKHUD', '~> 4.0'
pod '1PasswordExtension', '~> 1.8'
end
target 'MyAppKit' do
pod 'Fuzi', '~> 1.0'
pod 'RealmSwift', '~> 2.0'
pod 'Alamofire', '~> 4.0'
pod 'KeychainAccess', '~> 3.0'
pod 'Result', '~> 3.0'
target 'MyAppWidget' do
inherit! :search_paths
end
end
And that's it. I would say that the old behaviour was more obvious and didn't require reading up on "podfile target inheritance". I did learn a lot though. Cheers!
How to import a Cocoapod into an App Extension?
Check this pod file code as example, this pod file have 2 targets the app and the extension.
platform :ios, '9.0'
use_frameworks!
workspace 'MyWorkSpaceApp'
target 'MyApp' do
pod 'SwiftyUserDefaults'
pod 'Alamofire', '~> 4.0'
pod 'AlamofireImage', '~> 3.1'
#pod 'AlamofireNetworkActivityIndicator', '~> 2.0'
#pod "youtube-ios-player-helper", "~> 0.1.6"
#pod 'Alamofire-SwiftyJSON'
pod 'SwiftyJSON', '~> 3.0.0'
#pod 'SlideMenuControllerSwift'
pod 'UIColor_Hex_Swift', '~> 3.0.2'
#pod 'ALLoadingView', :git => 'https://github.com/ALoginov/ALLoadingView.git', :branch => 'swift3'
pod 'SDWebImage', '~>3.8'
#pod 'SwiftSpinner', :git => 'https://github.com/icanzilb/SwiftSpinner.git', :branch => 'swift3'
#pod 'SideMenu'
#pod 'Fabric'
#pod 'Crashlytics'
#pod 'IQKeyboardManagerSwift', '4.0.6'
#pod 'AELog'
#pod 'TestFairy'
#pod "AwesomeCache", "~> 5.0"
#pod 'Deviice'
#pod 'MKDropdownMenu'
#pod "HanekeSwift", :git => 'https://github.com/Haneke/HanekeSwift.git', :branch => 'feature/swift-3'
pod 'OneSignal', '~> 2.4'
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
end
target 'MyAppExtension' do
pod 'OneSignal', '~> 2.4'
end
end
I hope this helps you, best regards
Use Cocoapods with an App Extension
The proper way to do this is to update your podfile to add just 1 line :
link_with 'yourApp', 'yourAppExtension'
and a pod update should resolve the issue.
How can I add an app-extension into a private pod?
My understanding is that you can't. Nor you should. The parent app should know of all its targets itself. And given that every App Extension's bundleId is prefixed with with the bundleId of it parent app, it would require a lot of build tool wizardly to get the bundleId
, plist
, entitlements, provisioning profile, code signing right from the pod itself.
What you should do is intercept the notification from the host app, and then based on whatever parameter you have, you pass it onto your pod's serviceExtensionHandler.
Yet still if you don't want the headache of having multiple targets in your app then you can have a single target within the parent app and use some scripts to change the all the bundleId
, plist
, entitlements, provisioning profile, code signing
The best answer I found online was written by damian-rzeszot from this gist originally written and referenced from here:
alias plistbuddy=/usr/libexec/PlistBuddy
alias codesign=/usr/bin/codesign
#
# Bundle identifier
#
set_plist_bundle_identifier() {
local bundle_identifier="$1"
local plist_file="$2"
plistbuddy \
-c "set :CFBundleIdentifier $bundle_identifier" \
"$plist_file"
}
set_appex_bundle_identifier() {
local appex_target_name="$1"
local bundle_identifier_suffix="$2"
local bundle_identifier="$PRODUCT_BUNDLE_IDENTIFIER.$bundle_identifier_suffix"
local plist_file="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/Info.plist"
set_plist_bundle_identifier "$bundle_identifier" "$plist_file"
}
#
# Bundle version
#
set_plist_bundle_version() {
local bundle_version="$1"
local plist_file="$2"
plistbuddy \
-c "set :CFBundleShortVersionString $bundle_version" \
"$plist_file"
}
get_plsit_bundle_version() {
local plist_file="$1"
plistbuddy \
-c "Print :CFBundleShortVersionString" \
"$plist_file"
}
get_app_bundle_version() {
local plist_file="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"
get_plsit_bundle_version "$plist_file"
}
set_appex_bundle_version() {
local appex_target_name="$1"
local bundle_version="$2"
local plist_file="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/Info.plist"
set_plist_bundle_version "$bundle_version" "$plist_file"
}
#
# Bundle build
#
set_plist_bundle_build() {
local bundle_build="$1"
local plist_file="$2"
plistbuddy \
-c "set :CFBundleVersion $bundle_build" \
"$plist_file"
}
get_plist_bundle_build() {
local plist_file="$1"
plistbuddy \
-c "Print :CFBundleVersion" \
"$plist_file"
}
set_appex_bundle_build() {
local appex_target_name="$1"
local bundle_version="$2"
local plist_file="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/Info.plist"
set_plist_bundle_build "$bundle_version" "$plist_file"
}
get_app_bundle_build() {
local plist_file="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"
get_plist_bundle_build "$plist_file"
}
#
# Code signing
#
prepare_entitlements_file() {
local appex_target_name="$1"
local bundle_identifier_suffix="$2"
local output_file="$3"
local original_entitlements="$CONFIGURATION_TEMP_DIR/$appex_target_name.build/$appex_target_name.appex.xcent"
local bundle_identifier="$DEVELOPMENT_TEAM.$PRODUCT_BUNDLE_IDENTIFIER.$bundle_identifier_suffix"
cp "$original_entitlements" "$output_file"
if [[ $CONFIGURATION == "Release" ]]
then
plistbuddy \
-c "set :application-identifier $bundle_identifier" \
"$output_file"
plistbuddy \
-c "set :keychain-access-groups:0 $bundle_identifier" \
"$output_file"
fi
}
copy_provisioning_profile() {
local appex_target_name="$1"
local provision_source="$2"
local provision_destination="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/$EMBEDDED_PROFILE_NAME"
cp "$provision_source" "$provision_destination"
}
resign_appex() {
local appex_target_name="$1"
local entitlements_file="$2"
codesign \
--force \
--sign "$EXPANDED_CODE_SIGN_IDENTITY" \
--entitlements "$entitlements_file" \
--timestamp=none \
"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex"
}
#
#
#
#
#
set_appex_bundle_identifier \
"NotificationService" \
"notification-service"
set_appex_bundle_version \
"NotificationService" \
`get_app_bundle_version`
set_appex_bundle_build \
"NotificationService" \
`get_app_bundle_build`
# Be careful if using `keychain-access-groups` entitlement
prepare_entitlements_file \
"NotificationService" \
"notification-service" \
"$DERIVED_SOURCES_DIR/NotificationService-Entitlements.plist"
copy_provisioning_profile \
"NotificationService" \
"$SOURCE_ROOT/../.github/appstore/$TARGET_NAME/profiles/notification-service.mobileprovision"
resign_appex \
"NotificationService" \
"$DERIVED_SOURCES_DIR/NotificationService-Entitlements.plist"
cocoapods in library not found in app extension
Your extension needs its own bridging header. Add one, import the cocoapod, follow this answer if you need to here, go.
Related Topics
Present Uiviewcontroller as a Modal with Transparent Background
Rxswift Map and Flatmap Difference
How to Link a .Sks File to a .Swift File in Spritekit
Firebase Storage Downloadurl()' Is Deprecated: Use 'Storagereference.Downloadurlwithcompletion()
Swiftui - Two Buttons in a List
How to Copy a Struct and Modify One of Its Properties at the Same Time
Protocol Extension on an Objc Protocol
How to Conform to Nscopying and Implement Copywithzone in Swift 2
In Swift, How to Have a Uiscrollview Subclass That Has an Internal and External Delegate
Dynamically Change Text of Realitykit Entity
Core Data: Failed to Load Model
Iso8601 Date JSON Decoding Using Swift4
Swift Convert String to Unsafemutablepointer<Int8>
Programmatically Creating Constraints Bound to View Controller Margins
Implementing Nscopying in Swift with Subclasses
Using Non Ns_Enum Objective-C Enum in Swift