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.
Downgrade the CocoaPods pod version to 7.67.0
. (-:
Podfile
pod 'Google-Mobile-Ads-SDK', '7.67.0'
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+). XCFramework
s 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.
According to Google Developer in this link.
We are aware of this issue -- .xcframework is generally incompatible with .xib files. This is a Apple bug that we don't know when it'll get fixed.
As a temporary workaround, you could make a manual copy of the GADNativeAdView.h file to include in your project. You should then see all the outlets appearing in Interface Builder as expected.
I am successfully able to get the outlets following this workaround.
Here's what you need to do
GADNativeAd.h
. You can open this file by setting the class of a view in IB as GADNativeAdView
. Then click on the disclosure arrow to open the class. Make sure to change it back to whatever it was originally.Now create a new file i.e header file. Name it GADNativeAd.h
.
Paste the contents of that file in this newly created file.
Build the project once.
You should now be seeing the outlets in your xib's Connection Inspector.
Refrain from falling back to a working version as iOS ATT changes won't be present in them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With