Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
752 views
in Technique[技术] by (71.8m points)

ios - Is this the correct way to create dynamic/embedded framework with embedded cocoa pods?

I am trying to create a Dynamic Framework to share the code among various extensions of my app.

Problem :

Here is my project structure.

enter image description here

MyFrameworks is a network layer of my app which inherently uses Alamofire. So structured my pod file as follow.

platform :ios, '9.0'
use_frameworks!

workspace 'CocoaPodsProjectworkspace'

def shared_pods
    pod 'Alamofire'
    pod 'SwiftyJSON'
end

target 'CocoaPodsProject' do
    project 'CocoaPodsProject.xcodeproj'
    # Pods for CocoaPodsProject
end

target 'MyFramework' do
    project 'MyFramework/MyFramework.xcodeproj'
    shared_pods
end

target 'CocoaPodsProjectTests' do

end

target 'CocoaPodsProjectUITests' do

end

On building the framework when I drag it as embedded binary to my Main project I get the error.

dyld: Library not loaded: .framework/Alamofire Referenced from: /Users/sandeep/Library/Developer/Xcode/DerivedData/CocoaPodsProjectworkspace-enpobdyluhbxdwazuvbfogcspfof/Build/Products/Debug-iphonesimulator/MyFramework.framework/MyFramework Reason: image not found

Solutions I tried :

  • Declaring the pods_frameworks.framework as optional in linked binaries.
  • Tried changing RunPath Search path of framework Dynamic Library
  • Install name Running pod deintegrate and running pod install again.
  • Deleting derived data and relinking framework all lead to same problem.

Solution that worked :

I realized that MyFramework.framework was trying to find the Alamofire.framework in a wrong directory and it was alway trying to search relative to project/target using the framework . So the simplest solution that I could find was to modify pod file as follow.

platform :ios, '9.0'
use_frameworks!

workspace 'CocoaPodsProjectworkspace'

def shared_pods
    pod 'Alamofire'
    pod 'SwiftyJSON'
end

target 'CocoaPodsProject' do
    project 'CocoaPodsProject.xcodeproj'
    shared_pods
    # Pods for CocoaPodsProject
end

target 'MyFramework' do
    project 'MyFramework/MyFramework.xcodeproj'
    shared_pods
end

target 'CocoaPodsProjectTests' do

end

target 'CocoaPodsProjectUITests' do

end 

As you can see I added the shared_pods to both main app and my framework project and their respective targets. Now everything works smooth. I neither had to make pods_framework optional nor had to modify the build settings of MyFramework.

Question:

Adding the shared repos to all the projects and their targets which wants to use my framework looks little redundant. Is there a better way I can specify Myframework.framework to read all its dependencies rather than reading from project using it?

I have raised a issue for the same on CocoaPods Git repo. But because it isn't inherently a issue they might not revert back. Hence posting it as a question here.Link to issue : https://github.com/CocoaPods/CocoaPods/issues/6901 if it helps.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Solved it by creating a cocoa pod for my custom Framework and using cocoa pods dependency .

Step 1 : Clean the Main/Parent project

  • Removed MyFramework from the project (which was added as sub project) and remove MyFramework.framework added in embedded library of projects General settings.
  • Run pod deintegrate (to de-integrate the pod already added to
    project)
  • Now that the project is clean and does not have any pod added initialized the pod by running pod init

Step 2: Create a Pod for my Framework

  • Using cd command navigate to MyFramework project and once you are in MyFramework's root folder run pod spec create MyFramework
  • This will create a file named MyFramework.podspec in the MyFramework's root folder. Open MyFramework.podspec using any of the editor tool and update it as shown in tutorial https://www.raywenderlich.com/126365/ios-frameworks-tutorial

  • Most important step which is not there in this tutorial is how to add cocoa pods dependency that our framework needs to build. Turns out thats the most easiest part. In my case I needed SwiftyJSON and Alamofire so in .podspec file I added,

s.dependency 'Alamofire'

s.dependency 'SwiftyJSON'

Step 3:

  • Now open the Main/Parent projects Podfile and update it as shown below.
target 'CocoaPodsProject' do
  use_frameworks!
  pod 'TestFramework', :path => 'TestFramework/'
end

What it did is, it tells main project to add TestFramework as dependency and installs TestFramework in Framework folder of main project. Because TestFramework in itself has dependency to Alamofire & SwiftyJSON when you run pod install it will not only install Alamofire but also installs SwiftyJSON and adds it to TestFramework's Framework folder.

Thats all. Now your TestFramework can access Alamofire and SwiftyJSON and Main/Patent project can access TestFramework

If you want to now update TestFramework code, till u finish develop add it as subproject to Main project (This is necessary because if you open TestFramework.xcproj u won't see Alamofire/Swifty JSON. You have to open the Parent project's workspace itself hence this solution). Once u are done with development if u decide to remove the TestFramework as subproject u can do that :)

Finally If you decide to add additional extensions to app, Lets say u add Today extension all u have to do is to modify ur Podfile as follow.

target 'CocoaPodsProject' do
  use_frameworks!
  pod 'TestFramework', :path => 'TestFramework/'
end

target 'CocoapodsToday' do
  use_frameworks!
  pod 'TestFramework', :path => 'TestFramework/'
end

Woo hooo :) Now add your frameworks to as many extensions you want :) Hope it helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...