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

[Idea] Centralized Cache #62

Open
savage7 opened this issue Jan 31, 2021 · 1 comment
Open

[Idea] Centralized Cache #62

savage7 opened this issue Jan 31, 2021 · 1 comment

Comments

@savage7
Copy link

savage7 commented Jan 31, 2021

I really love your plugin and its a massive time saver 😊

I just want to share my basic idea which would lead to a massive change in the architecture and workflow of the plugin.
On the other hand I could bring use a centralized cache :)

I would be nice I you could share your thoughts on this.

Workaround for Realm

I had some trouble with Realm (#57).
While I was not able to resolve these issues I reworked them by creating a "binary pod" of Realm.

I prebuilt it myself (which is pretty easy but a manual task...) and put it on a interal git repo, than I created a Podspec which uses the internal podspec repo together with the offical cdn repo.
By this the official Realm/RealmSwift Pod is overruled with my internal binary version.
The clou:
I also use RxRealm, which depends on RealmSwift. By overriding the dependency with a binary version, the pod resolution still works.
This "workaround" made me thinking, if we could create a more global, not project specific binary cache. The global cache could work more like a maven repository.

A few preconditions for this, for making the cache relatively stable:

  • host xcframeworks
  • build all archs
  • build with library evolution support

I've built my binary repo with this basic scheme, mirroring the podspec repo:
PodName/Version/PodName.xcframework.zip

i.e:
Realm/10.5.1/Realm.xcframeworks.zip
RealmSwift/10.5.1/RealmSwift.xcframework.zip

I created Podspecs like these:

Pod::Spec.new do |s|
  s.name         = 'Realm'
  s.version      = '10.5.1'
 ....
  s.platform = :ios, '11.0'
  s.source = { git: 'binary_pods.git' }
  s.ios.vendored_frameworks = "#{s.name}/#{s.version}/#{s.name}.xcframework"
end

In the Podfile there are two ways to use this:
pod 'Realm', '10.5.1', source: 'cocoapods_binary_specs.git'
or

source: 'cocoapods_binary_specs.git'
pod 'Realm', '10.5.1'

However this will trigger a warning, that i.e. the Realm pod is found multiple sources. This can be silenced with by setting warn_for_multiple_pod_sources.

This is just a basic example, but it shows how we could basicly overwrite any source code dependency with a binary verison.

Basic proposal

Currently we have a binary cache per project, which cannot be versioned.
Cached artifacts, cannot be shared.
We have nothing like a "maven repository".
I want to keep the changes to the podfile minimal by only adding a new source (no explicit pod_binary).

pod binary prebuild --push behavior:
option 1, prebuild all pods:

  • builds all dependencies as xcframeworks for a specific Podfile
  • searches all pods and find dependencies
  • tries to build every pod

option 2, prebuild a single pod:
pod binary prebuild --push Resolver:1.4.0
find a pod and build that exact version.
also build all dependencies of the pod.

  • binaries are added versioned (like Realm/10.5.1/Realm.xcframeworks.zip) to the central cache
  • create binary Podspecs and push them to cocoapods_binary_specs.git
  • add transitive dependencies to the generated binary Podspecs

Usage

  • Podfile has an additional source i.e. source: 'cocoapods_binary_specs.git'
  • now "binary_pod" function would be used explicitly
  • cocoapods_binary_pods would not integrate the xcframework itself, since the specs from cocoapods_binary_specs are used
@savage7 savage7 changed the title [idea] Centralized Cache [Idea] Centralized Cache Jan 31, 2021
@trinhngocthuyen
Copy link
Contributor

Hi @savage7,
You brought up a very interesting idea. And it is actually similar to one of our items for improvements in the long term:

  • The cache frameworks are hosted somewhere else, in a store (like CDN). This store can be shared across projects depending on your needs.
  • The cache_repo git repo only contains metadata and files other than prebuilt frameworks, just enough for cache validation.
    This helps reduce the time to fetch cache because only cache-hit frameworks should be fetched.

So, I'd imagine it shall develop into that form in the long run.

However, I think we need to emphasize that the prebuilt frameworks are still specific to the project because those frameworks are built with a specific configuration (Debug/Release), project build settings, and very much affected by the custom build settings (if set) by Podfile pre_install/post_install hooks.
For example, if the pre_install/post_install hook in Podfile sets a framework as static like this:

pre_install do |installer|
  installer.pods_project.targets.each do |target|
    make_static(target)
  end
end

Then the prebuilt framework should be a static framework, and hence, cannot be used in other projects that require it to be dynamic.

Therefore, the idea of a centralized cache store could be adopted but please keep in mind the constraint above for the global cache setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants