Quickest way to add Carthage in Xcode Project - ios

What is quickest way to add dependencies in Xcode project using Carthage.
How to add or edit dependencies later.

Install Carthage
Download Carthage
Open terminal
Terminal: cd ~/Path/To/Folder Containing Project
Create Carthage file as:
Terminal: touch Cartfile
Open Cartfile file from project folder and add required dependency
Example Cartfile file
github "Alamofire/Alamofire" == 4.5
github "Alamofire/AlamofireImage"
After Editing Cartfile file save it.
Run following command from terminal
Terminal: carthage update --platform iOS
xCode > Build phases
Plus button on top left > New Run Script Phases
Run Script > Shell script window > add following:
/usr/local/bin/carthage copy-frameworks
Run Script > Input file window > add following:
$(SRCROOT)/Carthage/Build/iOS/DependencyName.framework
Link Binary With Libraries > Plus button > Add Other > Navigate to
Project Folder > Carthage > Build > iOS >
Framework to add
Done

Using Carthage flow
[iOS Dependency manager]
TL;DR:
Download dependency -> build fat binary -> it should be imported -> slice for release
Long version:
Installing Carthage
//Homebrew
brew install carthage
Create Cartfile file at the project(.xcodeproj)/workspace(.xcworkspace) directory
Modify Cartfile. Add necessary dependency == repo
github "<owner>/<repo>" == <version>
Run carthage update under Cartfile location. High level logic:
`carthage update [dependency]` {
- reads `Cartfile`, resolves dependency graph and generates `Cartfile.resolved` to store a list of versions that will be actually built
//--no-use-binaries - this flag force a Carthage to not use a `Prebuilt framework`
//--no-build - this flag skip a building step - `carthage build`
`carthage bootstrap [dependency]` {
- reads `Cartfile.resolved`
`carthage checkout [dependency]` {
`carthage fetch <path>` {
- fetch dependency from `Cartfile.resolved` into `~/Library/Caches/org.carthage.CarthageKit/` folder
}
- checkout/move a dependency from `~/Library/Caches/org.carthage.CarthageKit/` to generated `Carthage/Checkouts` folder
}
`carthage build [dependency]` {
- builds all `shared frameworks schemes` from `Carthage/Checkouts` into generated `Carthage/Build` folder
//--no-skip-current - (+current consumer)this flag also builds all `shared frameworks schemes` of a consumer workspace/project(in addition to `Carthage/Checkouts` folder)
}
}
}
Drag and drop builded frameworks to General -> Frameworks and Libraries
//framework location
<cartfile_path>/Carthage/Build/
Run the next script. This step is important because carthage build a fat binary(arm64... + x86_64) using lipo[About]. Apple reject application which uses it. That is why you should add this extra step to cut architecture for simulator(x86_64)
Build Phases -> + -> New Run Script phase ->
// /usr/local/bin/carthage - path to Carthage, copy-frameworks - command which sets a necessary architecture and copies framework to an application bundle
Shell -> /usr/local/bin/carthage copy-frameworks
//path to a generated Carthage/Build
Input files -> + -> $(SRCROOT)/Carthage/Build/<platform>/<name>.framework
*Any carthage command should be called from Cartfile folder
If you run into some error
This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/2q/jhrcxkmx49g21lydqfrf26ph0000gn/T/carthage-xcodebuild.AySUH3.log
//you can use open command to review the log
open /var/folders/2q/jhrcxkmx49g21lydqfrf26ph0000gn/T/carthage-xcodebuild.AySUH3.log
Crear Carthage cache
rm -rf ~/Library/Caches/org.carthage.CarthageKit
Get stuck on update
carthage update --platform ios --verbose --new-resolver
//e.g.
//The dependency graph contained a cycle
Use XCFramework[About] --use-xcframeworks
//error
Building universal frameworks with common architectures is not possible. The device and simulator slices for "<schema_name>" both build for: arm64
Rebuild with --use-xcframeworks to create an xcframework bundle instead.
//solution
carthage update --platform ios --verbose --new-resolver --use-xcframeworks
[Carthage --no-use-binaries]
[Fast Carthage build]
[Local Carthage]

Install carthage on your mac: brew install carthage
Create a Cartfile in the project root directory, e.g. vim Cartfile and paste:
github "AFNetworking/AFNetworking" ~> 4.0
Build the frameworks: Run carthage update --platform iOS
Warning: dependending on the library you are using, you'll need to follow their instructions on what carthage update command to run specifically. You may need to run e.g. carthage update --use-xcframeworks --platform iOS --no-use-binaries instead. Check their readme.
Add it to Xcode: In finder, navigate to $project_dir/Carthage/Build. You will find a FrameworkName.framework or FrameworkName.xcframework. Drag the .framework/ .xcframework into your Xcode Project (in the project navigator).

Related

library not found for -lRCTOrientation

I'm very beginner in React Native, I build a mobile application which is working OK an android, but when I tried to generate the IPA for iOS using Xcode, I faced this issue
ld: library not found for -lRCTOrientation
clang: error: linker command failed with exit code 1 (use -v to see invocation).
RCTOrientation is shown in red color and i can't find this package in my project folder
Try:
1)
in Xcode make sure you have followed these 3 steps:
a) Add node_modules/react-native-orientation/iOS/RCTOrientation.xcodeproj to your xcode project, usually under the Libraries group
It should show up somewhere in a list like this:
b) add libRCTOrientation.a (from Products under RCTOrientation.xcodeproj) to build target's Linked Frameworks and Libraries list
It should show somewhere in a list like this:
c) Add $(SRCROOT)/../node_modules/react-native-orientation/iOS/RCTOrientation/ to Project Name -> Build Settings -> Header Search Paths
Make sure that path is correct, in my case I had to add /../ inside it, as above for my RN project, the rn-orientation docs specify that without /../.
in Xcode go to Product menu and run Clean build folder
run react-native run-ios
If it still doesn't work try
2) Xcode go to Product menu, Schemes, Edit schemes, Build and make sure parallelized build is NOT enabled in Build Options
If it still doesn't work:
3) try to clean all the caches and restart npm:
rm -rf $TMPDIR/react-* && rm -rf $TMPDIR/metro-* && rm -rf $TMPDIR/haste-* && watchman watch-del-all && rm -rf ios/build && rm -rf node_modules && yarn install && npm start -- --reset-cache
If you don't have yarn installed just replace yarn word with npm in the above command.
Source for Xcode add library steps: https://github.com/yamill/react-native-orientation
UPDATE: RN 0.60+ supports autolinking and after installing the library with yarn or npm, running a pod install in ios folder, a cache clean, a JS server restart and a rebuild should fix such issues.

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

Integrate New relic using carthage package manager

Is there any way i can integrate New Relic sdk into my iOS project using carthage package manager? I don't want to use cocoa pods to do this since i am already using carthage package manager in my project.
Fetch the package via Carthage
To use Carthage there are a few steps. First inside of your Carthage/ Directory add a file called new_relic.json and add this to it:
{
"6.7.0": "https://download.newrelic.com/ios_agent/NewRelic_iOS_Agent_6.7.0.zip"
}
Then in your Cartfile add this line:
binary "./Carthage/new_relic.json" == 6.7.0
Finally run carthage update --platform ios
Integrate New Relic
After you run your update command and you have the package, go to the general tab and add all of these packages to the Linked Frameworks and Libraries section:
Add a bridging header to your project and add this line of code
#import "NewRelicAgent/NewRelic.h"
Then add this script to your build phases section:
SCRIPT=`/usr/bin/find "${SRCROOT}" -name newrelic_postbuild.sh | head -n 1`
/bin/sh "${SCRIPT}" "Your token here"
And this line of code to didFinishLaunchingWithOptions
NewRelic.start(withApplicationToken:"Your Token Here")

"No such module" error in Xcode 8

I get the "No such module" compilation error in Xcode 8.2.1 in my Swift project. I use Carthage with two modules: Alamofire and Fuzi. The Carthage/Build/iOS directory exists with the two framework files. The Build Settings/Framework Search Paths points to that directory. I have embedded the two framework files in General/Embedded Binaries. What am I missing?
You shouldn't need to embed the libraries; they should be added to Linked Frameworks and Libraries underneath the "General/Embedded Binaries" section. Make sure you have the Carthage copy-frameworks script added to your Build Phases.
From the Carthage documentation:
On your application targets’ “General” settings tab, in the “Linked
Frameworks and Libraries” section, drag and drop each framework you
want to use from the Carthage/Build folder on disk. On your
application targets’ “Build Phases” settings tab, click the “+” icon
and choose “New Run Script Phase”. Create a Run Script in which you
specify your shell (ex: bin/sh), add the following contents to the
script area below the shell:
/usr/local/bin/carthage copy-frameworks
and add the paths to the frameworks you want to use under “Input
Files”, e.g.:
$(SRCROOT)/Carthage/Build/iOS/Box.framework
$(SRCROOT)/Carthage/Build/iOS/Result.framework
$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework
This script works around an App Store submission bug triggered by
universal binaries and ensures that necessary bitcode-related files
and dSYMs are copied when archiving.
Firstly you check Carthage installed or not in your machine like the following command in your terminal
carthage version
If carthage is not installed in your machine try the following.
Download the latest release of Carthage, and double-click Carthage.pkg to run the installer. Click Continue, select a location to install to, then click Continue again, and finally click Install.
Then you can check carthage version.
If you are using existing project then move to project folder like
cd ~/Path/To/Starter/Project
Try the following command for update cartfile
carthage update —platform iOS
After installation/updation completed then try the following command
open carthage
You should see a Finder window pop up that contains two directories: Build and Checkouts.
In the Carthage Finder window, navigate into Build\iOS. Now, drag Alamofire.framework(for example) into the Linked Frameworks and Libraries section in Xcode:
Next, switch over to Build Phases and add a new Run Script build phase. Add the following command:
/usr/local/bin/carthage copy-frameworks
Click the + under Input Files and add an entry for each framework:
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework

Build failed with Realm and circleCI (with Carthage)

I keep getting linker error when running my project on circleCI saying that realm framework is not found. I have no problem with the framework on my development environment. I have checked the framework search path to include both $(inherited) and carthage build folder ($(PROJECT_DIR)/Carthage/Build/iOS). Below are the content of both my cartfile and circle.yml (circleCI's configuration file)
cartfile
github "Alamofire/Alamofire" ~> 3.4
github "Alamofire/AlamofireImage" ~> 2.0
github "SwiftyJSON/SwiftyJSON" ~> 2.3.0
github "SnapKit/SnapKit" >= 0.15.0
github "realm/realm-cocoa"
circle.yml
machine:
xcode:
version: "7.3"
dependencies:
pre:
- curl -O https://gist.githubusercontent.com/cabeca/cbaacbeb6a1cc4683aa5/raw/8e17f39f5a7413fd0559c9e6808e01b6fb514422/simulator_populator
- ruby ./simulator_populator
- carthage update --platform iOS
The 2 lines before carthage update are suggested by circleCI support tech to avoid issues with tvOS framework. I have also tried switching carthage update to carthage bootstrap with the same result. Below are the error message I get
From the screenshot it seems like the error occurs when it tries to link test files, but both test and uitest files are default created by xcode, I haven't added anything on it yet
but both test and uitest files are default created by xcode, I haven't added anything on it yet
I think that's the problem here. You need to make sure that both targets can find the framework via the build setting FRAMEWORK_SEARCH_PATHS. This should include the parent directory of the relevant frameworks, e.g. $(SRCROOT)/Carthage/Build/iOS. You can achieve that usually by dragging or adding the framework(s) to the "Link Binary with Libraries" build phase.
You need
carthage bootstrap --platform iOS
not
carthage update --platform iOS

Resources