orta / cocoapods-keys

A key value store for storing per-developer environment and application keys
MIT License
1.55k stars 93 forks source link

1.0.1 is always installed instead of 2.2.1 #224

Open SumoSimo opened 2 years ago

SumoSimo commented 2 years ago

I am developing an iOS app with a companion watchOS 7+ app. I noticed that version 1.0.1 of Keys is always installed after a pod install even though I have version 2.2.1 of the plugin installed.

1.0.1 doesn't seem to work with watchOS (or at least watchOS 7), so this is a blocker for me. How do I ensure that version 2.2.1 of Keys is installed after I do a pod install and enter the keys that my app uses?

ashfurrow commented 2 years ago

Probably the old version got installed globally for some reason. You can add a specific version to a Gemfile, and then run bundle install to download that version (and its dependencies). You may run into problems here, since there's probably a reason 1.0.1 keeps getting used instead. Maybe your macOS version of Ruby is outdated or something. The point is, that using a Gemfile at a specific version, and Bundler, will give you detailed error output that you can address.

Finally, make sure to run bundle exec pod install instead of just pod install, to force the Gemfile version to be used. Good luck :+1:

SumoSimo commented 2 years ago

Hi @ashfurrow, thank you for the reply!

I went ahead and gave your direction a go. I checked all of my ruby paths and ensured there weren't any global cocoapods-keys gems installed. I also have gem "cocoapods-keys", "~> 2.2.1" in my Gemfile. I ran bundle install, which worked perfectly, and bundle exec pod install, after which I entered my keys and saw the following output:

Analyzing dependencies
Downloading dependencies
Installing Keys (1.0.1)
Generating Pods project
Integrating client project
Pod installation complete! There are 5 dependencies from the Podfile and 6 total pods installed.

The output indicates that version 1.0.1 of Keys is being installed despite having version 2.2.1 of cocoapods-keys in my list of gems.

I looked around in the issues tracker and found #180, but I'm not sure if it's relevant or not.

ashfurrow commented 2 years ago

Ah, I see the issue. This is a misunderstanding – the 1.0.1 you see there is an implementation detail of how this repo works, and not the version number. Under the hood, this library generates a CocoaPods local podspec, which gets added as a "development pod" (you can see this in Xcode). The version number comes from the podspec template, here:

https://github.com/orta/cocoapods-keys/blob/fc97c5a31c785254ea79873854868870019540b1/templates/Keys.podspec.json#L3

This is where 1.0.1 comes from. You should be fine to use this now 👍 Let me know where I can clarify.

SumoSimo commented 2 years ago

I see. To step back a little, the root of my issue stems from the error No such module 'Keys'. Initially I thought it was a versioning issue, but it seems to be something else instead.

I have a module that is used in the main app target and also the watch extension, and that module imports Keys. The main app target is able to find Keys because I have the associated pods framework embedded. The watch extension has libPods-<watch-extension-name> WatchKit Extension.a embedded, which was generated after specifying the cocoapods-keys plugin for the watch-extension in the Podfile, but the compiler complains that it can't find Keys when building for the main app or the watch extension.

Here, libPods-<watch-extension-name> WatchKit Extension.a is embedded in the watch extension:

Embedded

Here, the WatchKit extension complains in the same way whether I am building for the main app or the watch extension. I left out the full error to redact information, but it's the typical "No such module" error:

Screen Shot 2021-11-22 at 1 40 24 PM

I noticed that libKeys.a is also generated, but the compiler also complains when that is embedded in the watch extension. I'm not quite sure what I'm missing here.

Here is my Podfile as well:

# Uncomment the next line to define a global platform for your project
platform :ios, '14.0'

target 'ProjectName' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for ProjectName
  pod 'GoogleMaps', '5.1.0'
  pod 'Google-Maps-iOS-Utils', '3.10.3'
  pod 'GooglePlaces'

  plugin 'cocoapods-keys', {
    :project => "ProjectName",
    :target => "ProjectName",
    :keys => [
      // Bunch of keys
    ]
  }

  target 'ProjectNameTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

target 'ProjectNameUITests' do
  # Pods for testing
end

target 'ProjectNameExtensionName WatchKit Extension' do
  plugin 'cocoapods-keys', {
    :project => "ProjectName",
    :target => "ProjectNameExtensionName WatchKit Extension",
    :keys => [
      // Bunch of keys
    ]
  }
end
ashfurrow commented 2 years ago

Hmm, I'm not sure, actually. What does your Podfile look like? I have zero watchOS development experience so I'm not sure how to proceed.

SumoSimo commented 2 years ago

I added my Podfile in my previous comment, but I've actually modified it just a bit. Here's the updated Podfile:

use_frameworks!

target 'ProjectName' do
  platform :ios, '14.0'

  # Pods for ProjectName
  // Pods

  plugin 'cocoapods-keys', {
    :project => "ProjectName",
    :target => "ProjectName",
    :keys => [
      // Bunch of keys
    ]
  }

end

target 'ProjectNameUITests' do
  # Pods for testing
  // Pods
end

target 'ProjectWatchExtensionName WatchKit Extension' do
  platform :watchos, '7.0'

  plugin 'cocoapods-keys', {
    :project => "ProjectName",
    :target => "ProjectWatchExtensionName WatchKit Extension",
    :keys => [
      // Bunch of keys
    ]
  }
end

This update was done to use .framework instead of .a, and it also moves the platform specifications for iOS and watchOS within their respective targets. This didn't help my situation, however.

I think one thing to note is that I'm trying to use the plugin for both targets. I don't know if that causes issues.

ashfurrow commented 2 years ago

Hmm, gotcha. Try moving the first plugin block to the top-level, and remove the second plugin block:

use_frameworks!

plugin 'cocoapods-keys', {
  :project => "ProjectName",
  :target => "ProjectName",
  :keys => [
    // Bunch of keys
  ]
}

target 'ProjectName' do
  platform :ios, '14.0'

  # Pods for ProjectName
  // Pods
end

target 'ProjectNameUITests' do
  # Pods for testing
  // Pods
end

target 'ProjectWatchExtensionName WatchKit Extension' do
  platform :watchos, '7.0'
end

This is how I've used the cocoa pods-keys plugin in the past:

https://github.com/artsy/eidolon/blob/878747ca319eedf0992fbe8c01e238bc6cc78083/Podfile

And it's been accessible automatically in the test target:

https://github.com/artsy/eidolon/blob/160767463524fb0219dc08552e9fe38023bd63b2/KioskTests/ArtsyAPISpec.swift#L6

Hopefully that works. Let us know!

SumoSimo commented 2 years ago

This didn't work either. Based on my observations (described below), it seems like only one target is able to use the plugin at a time because the source of the error alternates based on which plugin target is last declared. I could be wrong though.

Podfile attempt 1 - Watch extension generates error

Plugin declared with target = main app (last declared)

// Rest of Podfile

Podfile attempt 2 - Main app generates error

Plugin declared with target = main app
Plugin declared with target = watch extension (last declared)

// Rest of Podfile

Podfile attempt 3 - Main app generates error

Plugin declared with target = main app

// ...

target 'ProjectWatchExtensionName WatchKit Extension' do
  platform :watchos, '7.0'
  Plugin declared with target = watch extension (last declared)
end
SumoSimo commented 2 years ago

My current workaround is to move the generated files to the project and use it that way.

ashfurrow commented 2 years ago

That's a good workaround – thanks for sharing 🙇