Setting up library with CocoaPods and Swift Package Manager - ios

I have created a swift (iOS/MacOS) library on CocoaPods (BillboardSwiftLibrary). Generally, it has its assets and Classes folders which contain the source files.
I want my library to support Swift Package Manager, so I moved the source files from the Classes folder into a Sources folder outside the pod. However, they are still accessible from the Development pods.
Now my library won't build for Cocoapods launch but compiles for Swift Package Manager, I get the error below when I run pod lib lint BillboardSwiftLibrary.podspec
ERROR | file patterns: The source_files pattern did not match any
file.

I wrote a long series from scratch about "Creating iOS framework with CocoaPods, Carthage, SPM support and Travis for running test and Fastlane for release automation" on Medium. I hope it helps.
Creating Swift framework is easy but adding CocoaPods, Carthage and Swift Package Manager support at the same time can sounds like scary in the first place. In addition to that adding Travis to run test for all commits and adding Fastlane to automate release processes for all dependency managers looks like a horror movie. But don’t be afraid. After you finished this series, you can easily create your own Swift frameworks that uses all these tools to make it perfect!
Part 1 — Create CocoaPod and release it.: You will create your own CocoaPod and release it.
Part 2 — Add Carthage support: Your CocoaPod that is created and released at Part 1 will be installed via Carthage.
Part 3 — Add Swift Package Manager support: Your CocoaPod that is created and released at Part 1 will be installed via Swift Package Manager.
Part 4 — Integrate Travis to build example project and run tests for framework: Your framework that can be installed via CocoaPods, Carthage and Swift Package Manager runs tests automatically on Travis for every push on GitHub.
Part 5 — Integrate Fastlane to automate release processes by running just one line of command.:
Every time you want to release new version of your framework via CocoaPods, Carthage and Swift Package Manager, you have to go through following steps:
1- Implement changes for new version
2- Run tests to be sure they are working
3- Commit and push changes for new version.
4- Tag new version to git
git tag 0.1.1
git push origin 0.1.1
Carthage and Swift Package Manager installs your framework from GitHub. If you configure your framework correctly, it can be installed via Carthage or Swift Package Manager after this step. However, CocoaPods has 4 more steps to complete release processes.
5- Increment podspec version => i.e. s.version = '0.1.1'
6- Validate local podspec:
pod lib lint ODCustomFramework.podspec
7- Validate pod for release
pod spec lint ODCustomFramework.podspec
8- Release
pod trunk push ODCustomFramework.podspec
After Travis and Fastlane integration, steps 2, 4, 5, 6, 7 and 8 are automated and those steps are no longer needed to repeat every time you want to release new version.
1- Implement changes for new version
2- Commit and push changes for new version.
3- Travis runs tests automatically after every push.
4- Run following fastlane command to automate all release processes. (step 4, 5, 6, 7, 8)
exec fastlane major | minor | patch

From #Larme's comment, I found the answer.
In your podspec file, change the location of your classes to the sources folder.
So changed my s.source_files from to BillboardSwiftLibrary/Classes/**/* to Sources/**/* and pod lib lint BillboardSwiftLibrary.podspec worked fine.

Related

How to verify information in Carthage.resolved?

Cocoapods embed a step in the build phase to check if the Pods folder is in sync with the versions in Podfile.lock. This blocks the developer to work with the stale versions of the Pod with the following error:
error: The sandbox is not in sync with the Podfile.lock. Run 'pod
install' or update your CocoaPods installation.
Carthage has Cartfile.resolved, but how is it used to check if the Carthage Builds are fresh vs stale? Is it something that has to be manually enforced via some script?
Afaik the Carthage guides do not mention this topic at all. Usually you will be informed via failing compilation that a certain framework is not found, e.g. if you switched to a new branch where a new feature is implemented that needs framework XYZ. Then you know you have to run carthage bootstrap.
We have a script that runs so fast that you could even place it into the git hooks so it runs automatically after switching branches. The carthage part just cann the following command:
carthage bootstrap --use-ssh --use-xcframeworks --cache-builds
It makes sure carthage is up to date and it is fast since it uses cached builds. Runs fine for several years now.

Creating iOS Framework that is supported by CocoPods, Carthage, Swift Package Manager, Travis and Fastlane

How can we create iOS framework with CocoaPods, Carthage and Swift Package Manager support, and Travis for running tests and Fastlane for release automation?
I wrote a long series from scratch about "Creating iOS framework with CocoaPods, Carthage, SPM support and Travis for running test and Fastlane for release automation" on Medium. I hope it helps.
Creating Swift framework is easy but adding CocoaPods, Carthage and Swift Package Manager support at the same time can sounds like scary in the first place. In addition to that adding Travis to run test for all commits and adding Fastlane to automate release processes for all dependency managers looks like a horror movie. But don’t be afraid. After you finished this series, you can easily create your own Swift frameworks that uses all these tools to make it perfect!
Part 1 — Create CocoaPod and release it.: You will create your own CocoaPod and release it.
Part 2 — Add Carthage support: Your CocoaPod that is created and released at Part 1 will be installed via Carthage.
Part 3 — Add Swift Package Manager support: Your CocoaPod that is created and released at Part 1 will be installed via Swift Package Manager.
Part 4 — Integrate Travis to build example project and run tests for framework: Your framework that can be installed via CocoaPods, Carthage and Swift Package Manager runs tests automatically on Travis for every push on GitHub.
Part 5 — Integrate Fastlane to automate release processes by running just one line of command.:
Every time you want to release new version of your framework via CocoaPods, Carthage and Swift Package Manager, you have to go through following steps:
1- Implement changes for new version
2- Run tests to be sure they are working
3- Commit and push changes for new version.
4- Tag new version to git
git tag 0.1.1
git push origin 0.1.1
Carthage and Swift Package Manager installs your framework from GitHub. If you configure your framework correctly, it can be installed via Carthage or Swift Package Manager after this step. However, CocoaPods has 4 more steps to complete release processes.
5- Increment podspec version => i.e. s.version = '0.1.1'
6- Validate local podspec:
pod lib lint ODCustomFramework.podspec
7- Validate pod for release
pod spec lint ODCustomFramework.podspec
8- Release
pod trunk push ODCustomFramework.podspec
After Travis and Fastlane integration, steps 2, 4, 5, 6, 7 and 8 are automated and those steps are no longer needed to repeat every time you want to release new version.
1- Implement changes for new version
2- Commit and push changes for new version.
3- Travis runs tests automatically after every push.
4- Run following fastlane command to automate all release processes. (step 4, 5, 6, 7, 8)
exec fastlane major | minor | patch

Swift and Xcode: How to Build and Run a GitHub repository of iOS Application?

I'm interested on Running this GitHub repository of an iOS Application: https://github.com/septadev/SEPTA-iOS I opened the iSEPTA.xcodeproj file on XCode from the iSEPTA folder, but I'm getting these Buildtime Errors. For example: No such module 'ReSwift', and this is the window I get prompted when I select any of the yellow alerts, I'm not sure if I should perform these changes, yet.
Could it be some incomparability with my XCode and Swift versions?
Please, help!!
This project uses Carthage as a dependency management system for using external dependencies.
You should install Carthage to your computer and then run carthage update from the terminal in the root directory of the project. This will instal the dependencies and will allow you to run the project.
Take a look at Cartfile: it indicates this repo is using Carthage package manager. Follow their instructions to install dependent libraries
This repository requires Carthage ( https://github.com/Carthage/Carthage ) - this is a dependency manager. You can install it using Homebrew (https://brew.sh/)
brew install carthage
then you have to run carthageBuild.sh script (which runs carthage update):
./carthageBuild.sh
and then you have to open: Septa.xcworkspace file
This would be the correct solution if the project used Cocoapods. Since it uses Carthage, look to others answers unless you are referencing this answer to a similar issue.
You need to use Cocoapods to integrate the pods attached to the project. Often times projects will not come with them precompiled. Either you opened the blue project file with the *.xcodeproj extension instead of the white project file with the *.xcworkspace extension.... or you don't have the pods installed at all. In which case read below.
Instructions as follows:
cd to project directory
Install Cocoapods
sudo gem install cocoapods
Ensure the you have the given pods in your repo collection for install
pod repo update
Install the pods
pod install
Validate Project Settings
This is necessary until cocoapods v1.6 release (beta is out).
Open the white project file with the *.xcworkspace extension
After those steps are complete, the project should run normally.

What's the equivalent of "development pods" under Carthage?

The teams developing frameworks for our iOS app are migrating from Cocoapods to Carthage.
Under Cocoapods, I could set up dependencies as "development pods". For example, instead of having the main app download a specific version of an xyzzy dependency, I could set up xyzzy as a development pod and point it to my local directory where I had checked out xyzzy from its Git repo. While I was working in the main app's project, any edits I'd do to xyzzy's files would be made in that directory. This let me build and test changes immediately, and when I was ready to check them in, Git would find them in the xyzzy project's directory.
Under Carthage I haven't found a way to do this. I see http://allocinit.io/ios/debugging-carthage-dependencies/ which explains how to create symbolic links so that I can see the dependency source files to make debugging easier, but any edits I make to them are under the main application's Carthage/Builds directory.
How do I set up the equivalent of development pods under Carthage?
I believe Carthage doesn't have something similar to "development pods" yet.
But you could simulate "development pods" just following these steps:
Steps:
Add the .xcodeproj to your workspace
Remove all the dependencies you have in your project of the framework you added in step 1. (probably you may need to remove it from Build Phases -> Run Script -> Input Files too )
Go to General tab of the target you want to run, add the framework under Linked Frameworks and Libraries (it is going to take the one added from the .xcoproj)
(optional) you may need to run carthage bootstrap in the framework's repo you want to add locally.
That's it.
After that you will be able to run your project and update framework's code in the same workspace.
This works just as well as development pods for me, as of Xcode 8.3.3 and Carthage 0.24.0:
In app path, rm -rf Carthage
Point at the appropriate branch or tag in Cartfile
carthage update --use-submodules (generates .gitmodules and clones repo into Carthage/Checkouts)
In Xcode under project -> Build Phases -> Run Script, comment out the line that ends with carthage update --cache-builds if present.
Change to the General tab and remove the lib from Embedded Binaries
Right-click project, Add Files to app..., add lib from Carthage/Checkouts
Under project -> General, re-add the library, choosing the one you added in the previous step.
App should now build with the local lib. Make sure that your .gitignore has Carthage/{Build,Checkouts} and .gitmodules.
This answer is a summary of a successful implementation of the solution introduced here.
A cleaner solution is using local paths for dependencies in Cartfile.
Environment
Xcode 10.1
macOS 10.13.6
Step 1. Symbolic linking
1.1 Change $(SRCROOT_MAIN)/Carthage/Checkouts/$(DEVELOPING_FRAMEWORK_NAME) directory to a symbolic link pointing to source root directory of your developing framework $(SRCROOT_DEVELOPING_FRAMEWORK), where $(SRCROOT_MAIN) is source root directory of your main app. Backup existing directories before this change.
This linking enables version-controlled changes in your developing framework.
Syntax when using ln utility,
$ ln -s "$SRCROOT_DEVELOPING_FRAMEWORK" "$SRCROOT_MAIN/Carthage/Checkouts/$DEVELOPING_FRAMEWORK_NAME"
1.2 Change $(SRCROOT_DEVELOPING_FRAMEWORK)/Carthage/Build directory in your framework to a symbolic link pointing to $(SRCROOT_MAIN)/Carthage/Build directory. Backup existing directories before this change.
This linking enables access to all frameworks built by Carthage from both your developing framework and your main app.
Syntax when using ln utility,
$ ln -s "$SRCROOT_MAIN/Carthage/Build" "$SRCROOT_DEVELOPING_FRAMEWORK/Carthage/Build"
Step 2. Framework Replacement

2.1 Remove your developing framework in Xcode > YOUR_MAIN_APP > General > Linked Frameworks and Libraries (that is, the one located in $(SRCROOT_MAIN)/Carthage/Build/iOS).
2.2 Add $(DEVELOPING_FRAMEWORK_NAME).xcodeproj (found in directory pointed by $(SRCROOT_MAIN)/Carthage/Checkouts/$(DEVELOPING_FRAMEWORK_NAME) symbolic link) into your main app
2.3 Build the developing framework product for device and simulator
2.4 Add the new developing framework auto-detected by Xcode in Xcode > YOUR_MAIN_APP > General > Linked Frameworks and Libraries.
2.5 Add $(DEVELOPING_FRAMEWORK_NAME).framework as a target dependency by adding $(DEVELOPING_FRAMEWORK_NAME).framework in Xcode > YOUR_MAIN_APP > Build Phases > Target Dependencies.
2.6 Copy $(BUILT_PRODUCTS_DIR)/$(DEVELOPING_FRAMEWORK_NAME).framework to $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/$(DEVELOPING_FRAMEWORK_NAME).framework by adding a new input file $(BUILT_PRODUCTS_DIR)/$(DEVELOPING_FRAMEWORK_NAME).framework and a new output file $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/$(DEVELOPING_FRAMEWORK_NAME).framework in Xcode > YOUR_MAIN_APP > Build Phases > Run Script of Carthage Embed Framework.
Reference
Debugging Carthage Dependencies
https://allocinit.io/ios/debugging-carthage-dependencies/
Build Setting Reference
https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html

How to install a development Framework in MacOS for commandline build

I have an iOS application that needs to be integrated into CI/CD pipeline in CircleCI. Most of my dependencies have been added using CocoPods. There is one particular dependency of OpenCV2 that is manually compiled and used. On the local development machine, It is simple to use with drag & drop in Xcode. But, while running the build on a CI server. We don't have access to GUI and need to link dependency from the command line. I have not found much of the resources dealing with this issue.
I have tried few options from this link
https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Tasks/InstallingFrameworks.html
The framework that I am trying to use is compiled and zipped in an archive (opencv2.framework.zip and uploaded on Amazon S3. It is because the compiled framework is about 300 MB in size. So, I can't push it to the source repository. So, I download it using curl and unzip on CI machine. I have tried unzipping it to
/System/Library/Frameworks
/Library/Frameworks
~/Library/Frameworks
gym --scheme "project" --workspace "project.xcworkspace"
None of them really worked.I would like a way to register this framework in the system so that linker can find it while linking.
Suggest a way to extract framework into a location which linker can automatically look into.
Suggest a way where I can link framework manually from command line build
I have never used OpenCV but a quick pod search gives this result, so looks like they are already supporting cocoapods.....
pod search opencv
-> OpenCV2 (3.2.0)
OpenCV (Computer Vision) for iOS.
pod 'OpenCV2', '~> 3.2.0'
- Homepage: http://opencv.org
- Source: http://github.com/bcomeau/opencv/releases/download/3.2.0/opencv-3.2.0-ios-framework.zip
- Versions: 3.2.0 [master repo]
Second:
You can use Carthage https://github.com/Carthage/Carthage
You can use both Cocoapods and Carthage at the same time as long as they are not downloading the same dependencies.
Create a private repo, follow the carthage tutorial for uploading frameworks https://github.com/Carthage/Carthage#supporting-carthage-for-your-framework
then put opencv2 to your repo.
Then add your repo to your cartfile
Then before or after you install cocoapods, install carthage frameworks too.
It is a bit work but can solve your problem.
Third:
Looks like they also support Carthage
https://github.com/card-io/card.io-iOS-source/issues/32
Look at the last couple of comments..

Resources