Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] Add CocoaPods Podfile to the project template #23563

Closed
wants to merge 15 commits into from

Conversation

@fson
Copy link
Contributor

commented Feb 20, 2019

Summary

CocoaPods makes it easier to add new iOS dependencies to a project without having to manually edit Xcode projects. Editing Xcode projects is time consuming and merging changes to them difficult. Automating the changes to Xcode project react-native link is error prone. CocoaPods is a de-facto standard way to manage iOS dependencies and a central part of unimodules and upcoming improvements to react-native link.

This PR adds a Podfile to the default project template of React Native. To use a project with CocoaPods, after creating it, run cd ios; pod install and use the created <projectname>.xcworkspace file instead of the .xcodeproj file. (We could make this a part of react-native init so you only need to run one command when creating a project.)

Changelog

[iOS] [Added] - Add CocoaPods Podfile to the project template

Test Plan

Ran yarn pack in the repository root and then created a project and ran it successfully:

react-native init HelloWorld --version <full-path-here>/react-native/react-native-v1000.0.0.tgz
cd HelloWorld/ios
pod install
cd ..
react-native run-ios
@radeno

This comment has been minimized.

Copy link
Contributor

commented Feb 21, 2019

@fson same like in another PR. There should be iOS platform version 9.0
I like this PR

@fson fson changed the title Add CocoaPods Podfile to the project template [iOS] Add CocoaPods Podfile to the project template Feb 22, 2019

@fson fson force-pushed the fson:@fson/template-podfile branch from 8048dc7 to bb91638 Feb 22, 2019

@cpojer

This comment has been minimized.

Copy link
Contributor

commented Feb 26, 2019

@fson what's the status of this PR?

@pepibumur

This comment has been minimized.

Copy link

commented Feb 27, 2019

This idea is a great first step. Thanks for working on making the experience of using React Native more convenient.

I have a little question, have you tried running pod install in a clean environment where CocoaPods doesn't have the specs repository pre-fetched? At my company we run our CI builds in disposable environments so having CocoaPods updating the specs for every build would significantly increase the build time.

@zhigang1992

This comment has been minimized.

Copy link
Contributor

commented Mar 2, 2019

Some concerns regarding using CocoaPods by default.

https://rnfirebase.io/docs/v5.x.x/installation/ios#Option-2:-Cocoapods-(Not-Recommended)

But if we start recommending cocoapods we might be able to turn it around.

@zhigang1992

This comment has been minimized.

Copy link
Contributor

commented Mar 2, 2019

If we do provide Podfile should we include Podfile.lock?

Should we include Gemfile and Gemfile.lock to lock down the version of CocoaPods?

@FibreFoX

This comment has been minimized.

Copy link

commented Mar 3, 2019

@zhigang1992 is that still valid (yes, I saw that note on rnfirebase too)? As far as I can see, proper support for use_frameworks! is included since CocoaPods 1.5.0: http://blog.cocoapods.org/CocoaPods-1.5.0/
Even inside the documentation it states to have that supported (you might need to select the Single Page version): https://guides.cocoapods.org/syntax/podfile.html#tab_use_frameworks_bang

Not an iOS/XCode/CocoaPods-expert myself, but came across this note too, and having support for CocoaPods seems a more "clean" approach IMHO. 👍

@pepibumur

This comment has been minimized.

Copy link

commented Mar 5, 2019

Should we include Gemfile and Gemfile.lock to lock down the version of CocoaPods?

You should include them because it'd make builds reproducible. CocoaPods has generally been good at releasing new versions that are backward compatible but I'd better pin the version.

If we do provide Podfile should we include Podfile.lock?

If the pods are part of the packages resolved by npm or yarn, I don't think there's a need to include this one @zhigang1992. I'd only include it if you have dependencies in your Podfile that are pulled from the central registry.

@pvinis

This comment has been minimized.

Copy link
Contributor

commented Mar 5, 2019

I'm all for that, but when do we update this? What if I use a version later than the one used here, what then?

@radeno

This comment has been minimized.

Copy link
Contributor

commented Mar 5, 2019

@pvinis Gemfile is very similar to package.json you don't need to lock to specific version. But you can lock it to whole 1.X branch with gem 'cocoapods', '~> 1.6' in Gemfile.
Do not include Gemfile.lock, its same as yarn.lock. We don't need it in repo, it is user scope.
When platform is locked in Podfile why not locking minimal version Cocoapods ?

@pvinis

This comment has been minimized.

Copy link
Contributor

commented Mar 5, 2019

I didn't get exactly what you mean. The Gemfile having cocoapods in it is not like package.json. It would be like if package.json had the yarn version in it. That's why I ask. Right now, in many RN projects I have a Gemfile already, with cocoapods and fastlane for example. I guess that would be alright if the template has some version and I modify it, same as the template having a flowconfig version for example, that I also have modified before. I guess there will be no problem, I'm just saying.

@radeno

This comment has been minimized.

Copy link
Contributor

commented Mar 5, 2019

@pvinis do you say about Gemfile or Podfile?
Cocoapods is Ruby gem, and Ruby gems are defined by Gemfile. Podfile is Cocoapods definition file, inspired by Gemfile. It is already used many years in iOS development workflow. Another project is Carthage for iOS development.

If Podfile should be 100% compatible with very user, you need to specify minimal Cocoapods version. And for that you need Gemfile.

@pvinis

This comment has been minimized.

Copy link
Contributor

commented Mar 5, 2019

I'll just wait for the example. I know what you are saying. I understand it. (I even prefer carthage for some reasons.) Anyway, forget what I said. :)

@onmyway133

This comment has been minimized.

Copy link

commented Mar 5, 2019

@fson This PR will solve issue like this duplicated React framework invertase/react-native-firebase#414 (comment)? Because for now React comes as embedded and pod install adds another React pod

@pepibumur

This comment has been minimized.

Copy link

commented Mar 5, 2019

@fson let me know if you'd need any help with this work. I'm happy to make a contribution to the project.

@grabbou

This comment has been minimized.

Copy link
Collaborator

commented Mar 11, 2019

@fson, what's the status here? We wanted to ship it with 0.60 and we are about to cut that release soon (in fact, we could do it as early as today).

@fson

This comment has been minimized.

Copy link
Contributor Author

commented Mar 15, 2019

This PR should be ready to review and ship! (Sorry I had forgotten the draft status on 😅)

@FibreFoX

This comment has been minimized.

Copy link

commented Mar 22, 2019

@fson don't know exactly if this is related to this, but does you CI check if creating an iOS App Archive does work?

pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

This comment has been minimized.

Copy link
@orta

orta Mar 22, 2019

Collaborator

Not a blocker, but all of the above could be grabbed via a glob for Podspecs:

Dir.glob('../node_modules/react-native/**/*.podspec').each do |react_pod| 
  name = File.basename(react_pod, "podspec")
  path = File.dirname(react_pod)
  pod name, :path => path
end

This'll probably get deprecated by react-native-community/cli#256 eventually though

This comment has been minimized.

Copy link
@grabbou

grabbou Mar 22, 2019

Collaborator

This is so cool we can handle built-in podspecs with that API too.

This comment has been minimized.

Copy link
@fson

fson Mar 22, 2019

Author Contributor

@orta this is cool and much nicer for version upgrades. However, the code above doesn't produce the same result, because not all podspecs in the code base are included by default. These libraries were not linked in by default in the old Xcode project and correspondingly those pods are not dependencies of the React podspec:

./Libraries/ART/React-ART.podspec
./Libraries/CameraRoll/React-RCTCameraRoll.podspec
./Libraries/PushNotificationIOS/React-RCTPushNotification.podspec
./React/React-RCTFabric.podspec
./ReactCommon/fabric/graphics/React-graphics.podspec
./ReactCommon/React-Fabric.podspec
./ReactCommon/turbomodule/core/React-turbomodule-core.podspec

This comment has been minimized.

Copy link
@orta

orta Mar 22, 2019

Collaborator

Great point, I wonder if we make a way keep track of the default Podspecs inside React Native's codebase?

This comment has been minimized.

Copy link
@fson

fson Mar 22, 2019

Author Contributor

Right now it's these podspecs:

s.dependency "React-Core", version
s.dependency "React-DevSupport", version
s.dependency "React-RCTActionSheet", version
s.dependency "React-RCTAnimation", version
s.dependency "React-RCTBlob", version
s.dependency "React-RCTGeolocation", version
s.dependency "React-RCTImage", version
s.dependency "React-RCTLinking", version
s.dependency "React-RCTNetwork", version
s.dependency "React-RCTSettings", version
s.dependency "React-RCTText", version
s.dependency "React-RCTVibration", version
s.dependency "React-RCTWebSocket", version
and their transitive dependencies.

The podspec structure is supposed to mirror the Xcode projects as closely as possible, so I put podspecs next to the corresponding Xcode projects, but perhaps we could have a designated folder for all "core" podspecs that should be picked up by default?

This comment has been minimized.

Copy link
@orta

orta Mar 22, 2019

Collaborator

Interesting thanks, I wonder if we can use that then - it's a great source of truth.

Could have the podfile read the React.podspec, and add those dependencies (might end up being a bit of code (because the file paths are non-deterministic) )

I'll have a think

@cpojer

cpojer approved these changes Mar 22, 2019

Copy link
Contributor

left a comment

Thanks so much for working so hard on this. Let's ship it!

@facebook-github-bot
Copy link

left a comment

@cpojer is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@react-native-bot

This comment has been minimized.

Copy link
Collaborator

commented Mar 22, 2019

This pull request was successfully merged by @fson in cd8064b.

When will my fix make it into a release? | Upcoming Releases

@fson fson deleted the fson:@fson/template-podfile branch Mar 22, 2019

@msand

This comment has been minimized.

Copy link
Contributor

commented Mar 22, 2019

Great work! I would recommend checking that archive works correctly as well, at least before release. Historically this has been somewhat of a pain point, where everything seemed to work fine, except archive would be broken, or the release build would crash.

@cpojer

This comment has been minimized.

Copy link
Contributor

commented Mar 25, 2019

@msand could you add this check and send a PR?

@grabbou

This comment has been minimized.

Copy link
Collaborator

commented Apr 23, 2019

I've removed all the CocoaPods generated things from xcodeproj now, they'll get added automatically when you run pod install. Now when I tested it it worked both with 1.5.3 and 1.6.1.

I actually think we should bring this back. I think it's a good thing to generate "a final" project we can just open and run.

Right now, there's no xcworkspace at all and we can't even get run-ios to work before running a Podfile which is a big change to the workflow. I feel like presence of a Podfile might be omitted and we can get some reports of React.xcodeproj missing from Libraries.

@grabbou

This comment has been minimized.

Copy link
Collaborator

commented Apr 23, 2019

Also, react-native init ABC is not a git repository by default (shall we do it?)

That leaves pod install with these warnings:

fatal: not a git repository (or any of the parent directories): .git

@mikehardy

This comment has been minimized.

Copy link
Contributor

commented Apr 23, 2019

Installing cocoapods for the first time is medium-fearsome. I just did it recently, I remember going "oh ___, I guess I google cocoapods then...okay should I use brew? or gem?...okay brew, then...oh wow that's a lot of data downloading (I have a small connection)...etc etc".

You can tell which way I would vote based on dev-experience anyway - the template should come out of the box ready to start essentially, IMHO

I'm actually installing it on a machine right now and it's going to take 30+minutes just for me to do the "git sync" part of pod update

@cpojer

This comment has been minimized.

Copy link
Contributor

commented Apr 24, 2019

I think I would like an adaptive approach that does this:

  • If git is available, git init and make an initial commit with the project files. If git is not available, ignore this step.
  • If Cocoapods is available, set up the workspace, amend the template and commit the change (if git is available). If Cocoapods is unavailable, ask people to install it only when they start using react-native link for the first time.

That way creating a new project won't be slower or get in the way for people who are just getting started, and it comes with all the benefits when somebody is already familiar with these tools (assuming that installing the tools means some familiarity). What do you think?

@FibreFoX

This comment has been minimized.

Copy link

commented Apr 24, 2019

I can understand the reasoning against having CocoaPod as an additional build-dependency, so like @grabbou wrote, there should be a way to opt-in to using that Podfile-stuff.

@grabbou I would not favor for having a git-repository when running react-native init, mostly due to unneeded additional files in case I'm inside an existing git-repo and want to add this react-native project. Unlike @cpojer mentioned above, detecting a git-client does not tell anything about my intentions 😸

But to be honest, having nothing, like only the pure XCode-crap ... sorry, thats not useful, there has to be some way, like adding CocoaPod. Just add some lines to the "getting started" document and let "the community" give feedback to this. But I would see this as an optional step, not a forced one.

@grabbou

This comment has been minimized.

Copy link
Collaborator

commented Apr 24, 2019

@cpojer

That way creating a new project won't be slower or get in the way for people who are just getting started, and it comes with all the benefits when somebody is already familiar with these tools (assuming that installing the tools means some familiarity). What do you think?

Unfortunately, it will be slower, because installing CocoaPods and generating .xcworkspace takes time. You can't do it lazily (right when doing react-native link or react-native run-ios), because we don't have .xcworkspace generated.

When users would open the project directory right after react-native init, they will only see .xcodeproj which once they open, will throw them hundreds of warnings about missing React files. They will see a Podfile there, but if they are not aware of CocoaPods, they may not figure out running pod install is required to generate xcworkspace that they should use instead.

To fix that, we would have to run pod install right after react-native init. At this point, I don't see any benefits instead of just generating xcworkspace upfront.

@cpojer

This comment has been minimized.

Copy link
Contributor

commented Apr 24, 2019

@FibreFoX that seems like an easy fix to not run git if you are already within a git repo.
@grabbou I see what you mean! In that case I'm in favor of having this by default. The only thing I am worried about is requiring people to install Cocoapods to be able to run react-native init. I do not think it should be required until linking the first native dependency.

@grabbou

This comment has been minimized.

Copy link
Collaborator

commented Apr 24, 2019

@cpojer yeah, with my proposal, we generate all files upfront so you don't need to have run it while init. The template will have React Native preinstalled already with files generated.

First dependency linked is React Native itself, that's where's the "problem" we are talking about coming from.

@cpojer

This comment has been minimized.

Copy link
Contributor

commented Apr 24, 2019

I'm on board.

@FibreFoX

This comment has been minimized.

Copy link

commented Apr 24, 2019

@FibreFoX that seems like an easy fix to not run git if you are already within a git repo.

Maybe this can be added as some parameter instead of automagic?

Another thing to keep in mind: not all users want to use CocoaPod, some are using Carthage. So leaving the parts inside the existing .xcodeproj might be a valid option, and just having some kind of parameter while running react-native init to switch between the existing options (maybe even by using a template?!)

@orta

This comment has been minimized.

Copy link
Collaborator

commented Apr 24, 2019

+1 on running pod install on the cli template before shipping, then people won't need to do a pod install after initing a new template, only on adding new deps.

I think for edge cases like Carthage support people will make their own templates, you already have to have a reasonable understanding of Xcode to use it in a react native project so I wouldn't call them the target users

@pvinis

This comment has been minimized.

Copy link
Contributor

commented Apr 24, 2019

hm, it does suck though a bit though. maybe we can add the pod install or even better pod check && pod install when we start the packager or run react-native run-ios?
Or otherwise have an option like react-native init MyApp --no-cocoapods?

@benjarwar

This comment has been minimized.

Copy link

commented May 3, 2019

I'm curious about @onmyway133's comment above RE ending up with duplicate copies of React and its core dependencies.

Ran into this when I tried switching from Carthage to CocoaPods. Other react-native- third party frameworks ended up breaking, because CocoaPods automatically installed a Pods-managed version of React. Our NPM-managed dependencies installed an NPM version of React, which resulted in dupe versions between the two dependency managers. We never got our project to build properly, because various collaborators couldn't resolve to their dependencies correctly at compile-time, and we stuck with Carthage.

I guess the solution might be removing the Pods-managed version of React as outlined by @skurfuerst here. But if CocoaPods becomes the defacto way to manage libs via react-native link, are we going to run into issues in the other direction (aka Pods-managed dependencies can't find a Pods-managed version of React)?

@kattrali kattrali referenced this pull request May 9, 2019
@benjarwar

This comment has been minimized.

Copy link

commented May 10, 2019

@fson I know this issue is closed, but curious about how to officially get CocoaPods working with RN. It's given us nothing but trouble, see my comment above. I'm concerned about commands like react-native link become CocoaPods dependent.

We're currently experimenting with https://github.com/orta/cocoapods-fix-react-native/ to deal with the pathing collisions/issues. But that shim is stale and seems to require updates to work with latest RN versions.

@grabbou

This comment has been minimized.

Copy link
Collaborator

commented May 13, 2019

@benjarwar having CocoaPods to be the recommended and default way of consuming React Native iOS files, we will automatically get rid of issues with collisions and Pod definitions becoming stale.

If you have further concerns, please open them in the React Native CLI repository, where we can chat about anything that relates to CocoaPods and link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.