Xcode 接口生成器未检测到 Admob 框架类

Admob Framework class not detected by Xcode interface builder(Xcode 接口生成器未检测到 Admob 框架类)

本文介绍了Xcode 接口生成器未检测到 Admob 框架类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试在我的 iOS 应用中实现原生 Google adMob 广告并遵循 admob 官方教程:

我找到了一个 github 项目,它只是通过 Cocoapoding admob 框架实现了 admob 原生广告 (

几天来我一直在摸不着头脑,寻找解决方案没有运气.如果您知道发生这种情况的原因并且非常感谢您的帮助,请帮助我.

解决方案

TL;DR

将 CocoaPods pod 版本降级为 7.67.0.(-:

Podfile

pod 'Google-Mobile-Ads-SDK', '7.67.0'

说明

这是因为 GoogleMobileAds.framework7.68.0+ 中变成了 GoogleMobileAds.xcframework - 来源.这意味着 Objective C 运行时在框架(iOS 9)和主要目标(iOS 14.0+)之间是不同的.XCFrameworks 是一种特殊类型的二进制框架,所以在 iOS 版本编译完成后手动编辑它并没有什么不同,事实上,即使你在你的 Podfile 中指定一个 iOS 版本不会有什么不同.

主代码在底层有一个不同的、更快的 Objective-C 运行时,因此使用不同的数据结构跟踪类到 XCFramework.例如,如果在框架中定义了一个类别,即使不使用新的覆盖方法(在运行时),它也会存储在读写内存中.另一方面,iOS 14.0+ 中的 Objective-C 运行时不会加载这些方法,直到它们用于节省 RAM.这是旧 iOS 版本的重大更改,因为用于索引这些类的旧数据结构不再包括类别方法(在同一存储区域中)和依赖逻辑(读取这些数据结构)该框架将不再起作用.Method swizzling 的处理方式不同,这也是 GoogleUtilities 所做的(GoogleMobileAds 的依赖项),因此这可能会导致问题.因此,即使 IB Autocomplete 不起作用(那里没有大问题),也不会在运行时动态找到该类.我没有提到在新运行时对 method list 表示的更改,因为这超出了这个问题的范围,但是旧的方法列表在运行时仍然可以使用(non- 重大变化).

要解决这个问题,现在只需在 Podfile 中使用 7.67.0 版本.作为框架的最终用户,您无能为力,因为 podspec 将框架类型指定为 vendored_framework 并且只能在框架的源代码中进行编辑.我试图禁用 use_frameworks 但这无法编译.如果您可以为自己的框架编辑 podspec,则更改为静态框架是一个可行的解决方案(有一些注意事项).框架在构建时链接而不是静态框架的加载时间,因此您应该能够在 IB 中看到框架类,但是您必须使框架的依赖 pod 也是静态的(更多工作).更简单的等效方法是仅降级 pod,或在 Podfile 中禁用 use_frameworks.但是,框架具有更快的性能(链接时间)并且通常是首选,这就是为什么它们默认为 CocoaPods 启用的原因.

我还建议为这个错误创建一个新的 GitHub 问题,但看起来 SDK 不是开源的.也许这个错误会在未来由 Apple 解决,或者由 Google 在他们意识到它后解决,但这是一种解决方法.

I've been trying to implement native Google adMob ads in my iOS app and followed the admob official tutorial: https://developers.google.com/admob/ios/native/advanced

Whether I added the required admob framework manually or by CocoaPods, all the classes in the admob frameworks were not detected by the interface builder, so I could not set the Custom class of UIView to the wanted admob view classes. But weirdly I could use all the admob-related classes after the framework was imported in my swift files. See the below screenshot:

I found a github project, which did nothing but just implmented the admob native ad by Cocoapoding the admob framework (project link). I downloaded its source code and oddly the admob framework classes can be detected by interface face in this project.

I've been scratching my heads for a couple days and searching for the solution without luck. Please help me out if you have a clue why this happened and your help is highly apprecaited.

解决方案

TL;DR

Downgrade the CocoaPods pod version to 7.67.0. (-:

Podfile

pod 'Google-Mobile-Ads-SDK', '7.67.0'

Explanation

This is because GoogleMobileAds.framework became GoogleMobileAds.xcframework in 7.68.0+ - source. This means that the Objective C runtime differs between the framework (iOS 9) and the main target (iOS 14.0+). XCFrameworks are a special type of binary framework, so editing the iOS version manually after it has already been compiled won't make a difference, and in fact, even if you specify an iOS version in your Podfile it won't make a difference.

The main code has a different, faster Objective-C runtime under the hood, and so tracks classes using different data structures to the XCFramework. For example, if a category is defined in the framework, that will be stored in read-write memory even if the new overridden method isn't used (at runtime). On the other hand, the Objective-C runtime in iOS 14.0+ doesn't load these methods until they are used to save RAM. This is a breaking change for old iOS versions because the old data structures used to index these classes no longer include the category methods (in the same storage area) and dependent logic (that reads these data structures) in the framework will no longer work. Method swizzling is handled differently and this is what GoogleUtilities does as well (a dependency of GoogleMobileAds) so this can cause issues. So even if IB Autocomplete doesn't work (no big issue there), the class won't be found dynamically at runtime. I haven't mentioned changes to method list representation changes under the hood in the new runtime since that is out of scope for this question, but old method lists will still be usable at runtime (non-breaking change).

To work around this, just use the 7.67.0 version in your Podfile for now. You can't do anything else about this as an end-user of the framework, since the podspec specifies the framework type as a vendored_framework and this is only editable within the framework's source code. I tried to disable use_frameworks but that doesn't compile. If you can edit the podspec for your own frameworks, changing to a static framework is a viable solution (with caveats). The framework get linked at build time instead of load time for static frameworks so you should be able to see the framework class in IB, but then you have to make the dependent pods of the framework also static (more work). The easier equivalent is to just downgrade the pod, or disabling use_frameworks in the Podfile. However, frameworks have faster performance (linking time) and are generally preferred which is why they are enabled by default for CocoaPods.

I would also have suggested making a new GitHub Issue for this bug, but it looks like the SDK is not open-source. Maybe this bug will be resolved by Apple in the future, or by Google once they become aware of it but this is a workaround for now.

这篇关于Xcode 接口生成器未检测到 Admob 框架类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:Xcode 接口生成器未检测到 Admob 框架类

基础教程推荐