Use Cocoapods With an App Extension

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



Leave a reply



Submit