web-dev-qa-db-fra.com

La classe est implémentée dans les deux cas, l'un des deux sera utilisé. Lequel n'est pas défini

J'ai un problème avec les dépendances incluses dans Cocoapods.

J'ai un projet Framework (cible MyFramework), qui possède également une cible App (MyFrameworkExampleApp). Lorsque j'essaie d'exécuter l'application, je reçois une console pleine d'erreurs comme celle-ci:

La classe PodsDummy_AFNetworking est implémentée à la fois dans /private/var/containers/Bundle/Application/AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/Frameworks/MyFramework/MyFramework.fr/MyFramework/MyFr. /AD85D7EC-2652-4019-94FB-C799D0FBA69B/MyFrameworkExampleApp.app/MyFrameworkExampleApp (0x10107c558). Un des deux sera utilisé. Lequel n'est pas défini.

Le problème est que les erreurs proviennent des bibliothèques incluses uniquement dans la cible MyFramework.

Voici le contenu de mon podfile:

# Specify platform.
platform :ios, '9.0'

# Let's ignore all warnings from all pods
inhibit_all_warnings!

target 'MyFramework’ do

    # ReactiveCocoa for easier binding between UI and data models.
    pod 'ReactiveCocoa', '< 3.0'

    # ReactiveViewModel for easier handling of active/inactive view models.
    pod 'ReactiveViewModel', '0.3'

    # An Objective-C extension with some Nice helpers including @weakify/@strongify.
    pod 'libextobjc', '~> 0.4.1'

    # AFNetworking Security stuff
    pod 'AFNetworking/Security', '~> 2.5.4'

    # KZPropertyMapper to easily map JSON dicts to properties
    pod "KZPropertyMapper"

    # Simple wrapper for KeyChain
    pod 'UICKeyChainStore', '~> 2.0.6'

    # Animated gifs
    pod 'FLAnimatedImage', '~> 1.0'

    # Firebase Push notifications
    pod 'Firebase/Core'
    pod 'Firebase/Messaging'

    # Easy image downloading with cache.
    pod 'SDWebImage', '~> 3.7.2'

    # Activity indicator for RBSlider
    pod 'DGActivityIndicatorView'

end

target 'MyFrameworkExampleApp' do

    # Progress indicator
    pod 'MBProgressHUD', '~> 1.0.0'

    # Color picker
    pod 'iOS-Color-Picker'

    # Hockey SDK
    pod 'HockeySDK', '~> 5.0.0'

end

Comme vous pouvez le constater, App target n'hérite d'aucun pod, pas plus que je n'ai de pods globaux. Quelle pourrait en être la raison?

27
mag_zbc

Je ne connais pas la raison, mais si vous ouvrez le fichier Pods- [AppName] .debug.xcconfig créé par cocoapods, vous trouverez OTHER_LDFLAGS et vous verrez qu'il est lié aux mêmes frameworks que ceux de votre framework. Ainsi, si vous supprimez -framework [infrastructure dupliquée], l'avertissement disparaît.

Semble être une erreur de cocoapodes

21
David Bemerguy

J'ai aussi trouvé un autre script écrit par quelqu'un qui corrige le bogue automatiquement. C'est simplement faire la même chose que j'ai répondu ci-dessus. Ajoutez-le à votre podfile:

post_install do |installer|
    sharedLibrary = installer.aggregate_targets.find { |aggregate_target| aggregate_target.name == 'Pods-[MY_FRAMEWORK_TARGET]' }
    installer.aggregate_targets.each do |aggregate_target|
        if aggregate_target.name == 'Pods-[MY_APP_TARGET]'
            aggregate_target.xcconfigs.each do |config_name, config_file|
                sharedLibraryPodTargets = sharedLibrary.pod_targets
                aggregate_target.pod_targets.select { |pod_target| sharedLibraryPodTargets.include?(pod_target) }.each do |pod_target|
                    pod_target.specs.each do |spec|
                        frameworkPaths = unless spec.attributes_hash['ios'].nil? then spec.attributes_hash['ios']['vendored_frameworks'] else spec.attributes_hash['vendored_frameworks'] end || Set.new
                        frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
                            extension = File.extname filename
                            File.basename filename, extension
                        end
                    end
                    frameworkNames.each do |name|
                        if name != '[DUPLICATED_FRAMEWORK_1]' && name != '[DUPLICATED_FRAMEWORK_2]'
                            raise("Script is trying to remove unwanted flags: #{name}. Check it out!")
                        end
                        puts "Removing #{name} from OTHER_LDFLAGS"
                        config_file.frameworks.delete(name)
                    end
                end
            end
            xcconfig_path = aggregate_target.xcconfig_path(config_name)
            config_file.save_as(xcconfig_path)
        end
    end
end
7
David Bemerguy

Mise à jour: j'écris un article de blog pour ma solution: https://medium.com/@GalvinLi/tinysolution-fix-cocoapods-duplicate-implement-implement-warning-5a2e1a505ea8

Et un projet de démonstration: https://github.com/bestwnh/TinySolution


J'ai eu l'idée de la solution sur Internet, mais je ne peux pas trouver une solution qui fonctionne. Je crée donc une solution de contournement par moi-même. Peut-être que le code est un peu long, mais ça marche. J'espère que ça peut aider quelqu'un.

La auto_process_target(,,) est la fonction clé. Modifiez-la pour l'adapter à votre projet et tout devrait bien fonctionner. (Étant donné que j'utilise un cadre pour une cible à applications multiples, le paramètre de cible d'application est donc un tableau.)

post_install do |installer|

  # you should change the sample auto_process_target method call to fit your project

  # sample for the question
  auto_process_target(['MyFrameworkExampleApp'], 'MyFramework', installer)
  # sample for the multi app use on same framework
  auto_process_target(['exampleiOSApp', 'exampleMacApp'], 'exampleFramework', installer)

end

# the below code no need to modify

def auto_process_target(app_target_names, embedded_target_name, installer)
  words = find_words_at_embedded_target('Pods-' + embedded_target_name,
                                        installer)
  handle_app_targets(app_target_names.map{ |str| 'Pods-' + str },
                     words,
                     installer)
end

def find_line_with_start(str, start)
  str.each_line do |line|
      if line.start_with?(start)
        return line
      end
  end
  return nil
end

def remove_words(str, words)
  new_str = str
  words.each do |Word| 
    new_str = new_str.sub(Word, '')
  end
  return new_str
end

def find_words_at_embedded_target(target_name, installer)
  target = installer.pods_project.targets.find { |target| target.name == target_name }
  target.build_configurations.each do |config|
    xcconfig_path = config.base_configuration_reference.real_path
    xcconfig = File.read(xcconfig_path)
    old_line = find_line_with_start(xcconfig, "OTHER_LDFLAGS")

    if old_line == nil 
      next
    end
    words = old_line.split(' ').select{ |str| str.start_with?("-l") }.map{ |str| ' ' + str }
    return words
  end
end

def handle_app_targets(names, words, installer)
  installer.pods_project.targets.each do |target|
    if names.index(target.name) == nil
      next
    end
    puts "Updating #{target.name} OTHER_LDFLAGS"
    target.build_configurations.each do |config|
      xcconfig_path = config.base_configuration_reference.real_path
      xcconfig = File.read(xcconfig_path)
      old_line = find_line_with_start(xcconfig, "OTHER_LDFLAGS")

      if old_line == nil 
        next
      end
      new_line = remove_words(old_line, words)

      new_xcconfig = xcconfig.sub(old_line, new_line)
      File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
    end
  end
end

Si tout fonctionne. Tu verras Update xxxx OTHER_LDFLAGS lorsque vous pod install ou pod update. Puis l'avertissement a disparu.

enter image description here

1
Galvin

https://github.com/CocoaPods/CocoaPods/issues/7126#issuecomment-399395611

post_install do |installer|
    applicationTargets = [
        'Pods-SampleApp',
    ]
    libraryTargets = [
        'Pods-SampleLib',
    ]

    embedded_targets = installer.aggregate_targets.select { |aggregate_target|
        libraryTargets.include? aggregate_target.name
    }
    embedded_pod_targets = embedded_targets.flat_map { |embedded_target| embedded_target.pod_targets }
    Host_targets = installer.aggregate_targets.select { |aggregate_target|
        applicationTargets.include? aggregate_target.name
    }

    # We only want to remove pods from Application targets, not libraries
    Host_targets.each do |Host_target|
        Host_target.xcconfigs.each do |config_name, config_file|
            Host_target.pod_targets.each do |pod_target|
                if embedded_pod_targets.include? pod_target
                    pod_target.specs.each do |spec|
                        if spec.attributes_hash['ios'] != nil
                            frameworkPaths = spec.attributes_hash['ios']['vendored_frameworks']
                            else
                            frameworkPaths = spec.attributes_hash['vendored_frameworks']
                        end
                        if frameworkPaths != nil
                            frameworkNames = Array(frameworkPaths).map(&:to_s).map do |filename|
                                extension = File.extname filename
                                File.basename filename, extension
                            end
                            frameworkNames.each do |name|
                                puts "Removing #{name} from OTHER_LDFLAGS of target #{Host_target.name}"
                                config_file.frameworks.delete(name)
                            end
                        end
                    end
                end
            end
            xcconfig_path = Host_target.xcconfig_path(config_name)
            config_file.save_as(xcconfig_path)
        end
    end
end
1
Mateo Marin