Getting the latest code of a CocoaPods dependency

2019-08-24 22:15发布

This question is about how to get the latest code for CocoaPods-managed dependencies during development, i.e. without doing the whole "push a new podspec" dance.

Setup

Say we have three projects A, B, and C. The dependencies are such that A depends on B, and B depends on C. Each project resides in its own Git repository.

We figured we'd use a dummy minor version to identify the current state of the code. The podspecs reside in our own repository.

# A/Podfile
...
pod 'B', '1.dev'

# B/Podfile
...
pod 'C', '1.dev'

# B/B.podspec
Pod::Spec.new do |s|
    s.name = 'B'
    s.version = '1.dev'
    ...
    s.dependency = 'C', '1.dev'
end

# C/C.podspec
Pod::Spec.new do |s|
    s.name = 'C'
    s.version = '1.dev'
    ...
end

The Problem

We push a new commit to (the master branch of) C. We expect

A$ pod update

to retrieve the change. This does not happen.

Approaches

  1. Whenever we (know to) want to pull the dependencies anew, do:

    A$ rm -rf Pods/ Podfile.lock
    A$ pod cache clean --all
    A$ pod install
    

    This definitely gets the latest code. However, it's a sledgehammer that's neither convenient nor efficient to do after every pull in A, push in either B or C, or switching between branches in A.

  2. In order to stick close to the setup, we'd have to create a whole new set of podspecs and Podfiles after every (meaningful) set of commits on a master branch (i.e. a merge of a feature branch), all with a new version 1.x-y (y a build number or something); push the podspecs; and run pod update in A and B.

    While this may be feasible in a CI setup (which we unfortunately don't have, yet), it's prohibitive work to do manually. Git hooks may be a workaround.

  3. On non-version branches, do

    # A/Podfile
    ... 
    pod 'A', :git => "...", :branch => "master"
    

    That is, circumvent the podspec repo. Unfortunately, this won't work here becaus pod will inspect B.podspec and find its dependency C, which we can not specify in a similar way. Also, pod update always re-installs, no matter if there were new commits.

Question

Is there a good (low maintenance) way to track branches with CocoaPods? If not, what are alternatives?

1条回答
女痞
2楼-- · 2019-08-24 22:36

A possible solution is to use local pods.

Architecture for sample:

SomeWhere/BigFolder
          -- ProjectAWithItsPodSpecFiles
          -- ProjectBWithItsPodSpecFiles
          -- ProjectCWithItsPodSpecFiles

This way in your PodFile A, you do:

pod 'MyCustomPodB', :path => '../FolderPodB'
pod 'MyCustomPodC', :path => '../FolderPodC'

This add the possibility to modify yourself the classes of your pod without asking for a pod update/git pull and also not prompting the “MyFileInMyPod” is locked for editing and you may not be able to save your changes. Do you want to unlock it? from XCode each time.

How do we tell everyone to do so, meaning keeping the architecture of folders?

Using Repo, tool by Google!

What is this tool in a few lines:
It can pull from various git repositories at the same times keeping a synchronized work.
You have a manifest.xml files where you specify the repositories, the branches, and the local path (for the local architecture). Here is a tutorial. If you are using private repositories, I'd suggest using an HostAlias with SSH Keys.

My coworker continues to use Repo, I don't really. I keep pulling/pushing each one of them one by one using SourceTree.app, I used Repo only for the "starter" and that created me my whole local architecture.

In our own project:

Projects/MainApp
Projects/CoreClasses
Projects/Custo, Like Colors, etc.
Projects/OtherModule

I, most of the time, work on MainApp, and need to modify CoreClasses without any issue this way.

Sample of our Manifest.xml (in another private repository where there is almost only file):

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <remote name="remoteName" fetch="ssh://git@ourCommonAlias/RestOfTheGitPathExceptTheLastComponent"/>
    <default revision="masterBranchIsToSetByDefaultIfNeeded"
           remote="bitbucket"
           sync-j="4" />
    <project name="MainApp.git" remote="remoteName" path="BigFolder/MainApp"/> <!-- The name is the last component of the repository, the path the local path, the remote, the "start of the ssh give previously -->
    <project name="CoreClasses.git" remote="remoteName" path="BigFolder/CoreClasses"/>
    <project name="Custo.git" remote="remoteName" path="BigFolder/Custo" revision="someBranchIfNeededThere"/>
    <project name="OtherModule.git" remote="remoteName" path="BigFolder/OtherModule"/>

</manifest>
查看更多
登录 后发表回答