checkout / frames-ios

Frames iOS: making native card payments simple

Home Page:https://www.checkout.com/docs/integrate/sdks/ios-sdk

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Frames Cocoapod integration is broken from 4.0.2

rock88 opened this issue · comments

Describe the bug
Build with Frames 4.0.2/4.0.3 fail with error:

Multiple commands produce 'FramesCocoapodIssue.app/Assets.car'

To Reproduce
Steps to reproduce the behavior:

  1. Create new Xcode project from scrarch;
  2. Add Podfile with dependency on Frames:
platform :ios, '14.0'

target 'FramesCocoapodIssue' do
  pod 'Frames', '4.0.3'
end
  1. Run pod install
  2. Open workspace and build project

Expected behavior
Build should succeed.

Desktop (please complete the following information):

  • OS: macOS 13.0.1
  • Xcode: 14.2
  • Build for iOS Simulator with iOS 16.2

Additional context
Hi! I created a test project for reproduce this issue - https://github.com/rock88/FramesCocoapodIssue
If use Frames 4.0.1 all works as expected.

Issue appear in this PR: #359
I think preferred use Resources Bundle instead of just copy resources to application bundle. For include only Assets and Localizations you can use:

s.resource_bundles = {
  'Frames' => ['Source/Resources/**/*.{xcassets,strings}']
}

For access to this resources from Frames sources (Both SPM and Cocoapod):

#if COCOAPODS
extension Bundle {
    static let module = Bundle.main.path(forResource: "Frames", ofType: "bundle").flatMap { Bundle(path: $0) } ??
      Bundle(for: BundleToken.self).path(forResource: "Frames", ofType: "bundle").flatMap(Bundle.init) ??
      Bundle(for: BundleToken.self)
}

private final class BundleToken { }
#endif

// part of https://github.com/checkout/frames-ios/blob/main/Source/Extensions/StringExtensions.swift
extension String {
    func localized(comment: String = "") -> String {
        NSLocalizedString(self, bundle: .module, comment: comment)
    }

    func image() -> UIImage {
        UIImage(named: self, in: .module, compatibleWith: nil) ?? UIImage()
    }
}

Hi @rock88 ,

Thank you for taking time to open the issue and document it.

At this stage it would appear the source of the problem is in the Podfile shared.

Our ReadMe's Cocoapods Integration suggests using use_frameworks! in your podfile. This forces the dependency to be handled as a dynamic framework, rather than a static library.

So in your example Podfile you could write this instead:

target 'FramesCocoapodIssue' do
  use_frameworks!
  pod 'Frames', '4.0.3'
end

I have tried this in a local test project and if I remove use_frameworks! I encounter the behaviour you are documenting.

Please let us know if this solves your issue.

 
 
Separately, we would highly encourage you to give SPM a go as we have been finding it quicker to integrate, easier to keep updated & causing fewer issues.

Let us know if we can help further.

Hi @alex-ioja-yang-cko,

Ooh, I missed use_frameworks! in README. I was just checking what could be the failed build reason and found it related to Frames update, because earlier all work fine without use_frameworks!.
Yep, in our project we use a static libraries instead of frameworks and not planned move to frameworks... Also I'd like use SPM, but currently is a long term task.

I know it's a pain to maintain multiple package managers, so may I make a PR for support Cocoapod static library by adding Resource Bundle to podspec?

Hi @rock88 ,

I am unsure whether we would make that change on the repo. Personally I am not a specialist in Cocoapods and with the Christmas period we will not be seeing full team for a while, so we will be a little slower to consider this.

One thing I would say is that the reason for the PR you linked was that prior to it the assets were not correctly linked when building for AppStore. This was tested at the time with Xcode 14.0 & 14.1, so I would not know whether 14.2 behaves differently. It appeared to be a conflict between the Resource Bundle and the Product, both having the same name (Frames). There were 2 possible solutions, one was to name the resource asset differently (FramesAssets), updating the pod spec and the Bundle (similarly to what you showed in your solution suggestion, but using FramesAssets instead of Frames), the other was to simply not declare the name for the assets bundle (current version of podspec).
The solution we did in the PR seemed to have the same outcome, so we will be keen to compare if this behaviour is improved with your suggestion.

Alternatively, would mixing static & dynamic linking in cocoapods be of any help?

If you are attempting your version, do check whether you are able to see the assets (images immediately stand out) in a TestFlight distribution. Locally everything was looking well, the problem showed on AppStore builds.


Finally, on your point:

Also I'd like use SPM, but currently is a long term task

I have been meaning for a while to write an article on this but lacking the time. I have personally first used SPM alongside Cocoapods 3 years ago and have not found any notable problems. It was actually quite a nice experience getting to see both dependency managers alongside, and over time SPM proved to be more dependable.
It would be very interesting for me if you could share what challenges you're encountering in using SPM alongside Cocoapods, or any reasoning for avoiding to try it at all (I would say that with SPM being built into Xcode, the minor automation issues I met in the very early days were still easier to deal with than Cocoapods oddities) .

Hi @alex-ioja-yang-cko,

It appeared to be a conflict between the Resource Bundle and the Product, both having the same name (Frames).

Hm, for frameworks resources bundle should installing into framework, ie. Frames.framework/Frames.bundle, for example. Also Cocoapod generate different target names for library and resources bundle:

Screenshot 2022-12-21 at 21 30 48

In Payment.podspec we use:

Pod::Spec.new do |s|
  s.name = 'Payment'
  ...
  s.resource_bundle = {
    s.name => 'Resources/**/*.{xib,storyboard,xcassets,strings}'
  }
end

But I doesn't know how it work with frameworks.

Alternatively, would mixing static & dynamic linking in cocoapods be of any help?

Maybe it can help, I haven't tried to use this. I will check it later if not find any other solution.

If you are attempting your version, do check whether you are able to see the assets (images immediately stand out) in a TestFlight distribution. Locally everything was looking well, the problem showed on AppStore builds.

At the last week we released app with Frames 4.0.1, all works fine. I don't think what we face with any issue if return resources bundle. But yet again, frameworks can have other behavior and problem with AppStore build may return.


I watch for a long time to SPM and at this summer started move few pods to SPM. Our pods has few run scripts phases (depending of library we generate assets/strings/etc getters with SwiftGen). And SPM plugins doesn't work if I added more that one plugin to package. After one month it was fixed in next Xcode 14 Beta, so I continued my work. In total I move around 15 pods to SPM, it enough for basic examples.
All was fine, but when I start worked with our UIKit (in example project with local UIKit package, which has dependency on other package with Colors/Fonts/etc), after adding new file to UIKit package, Xcode start resolve package graph (it takes around 20s). If I just rename a file it happens again. And is a just one local package. Our app has 60 local pods, and I think currently it can slow developments process. Of course we have many local pods because our app is modular and each feature/screen/flow can develop isolated from main app.
With Cocoapod it just doesn't happen, I can rename file and run project without wait some time which take the Xcode.

Mix SPM and Cocoapods can make project poorly maintained. And it possible pods can links with SPM package and vice versa?

Anyway SPM is a great tool and and sooner or later we completely go to SPM =)

Hi @rock88,

Closing this stale issue now. Feel free to re-open, ask more or create a new one 🙂