Cannot debug Swift module/framework embedded in Objective-C app - xcode

Alternative titles (to aid searching)
Cannot debug Swift 2.3 framework linked to an Objective-C app in Xcode 8
error in auto-import: failed to get module 'XYZ' from AST context Xcode 8
Xcode 8 cannot debug Swift framework
warning: Swift error in module <XYZ>
Workaround for; Xcode Debugger cannot debug apps written in Objective-C only but that link against frameworks written in Swift only. (28312362)
I have an app written in Objective-C that links against some modules (frameworks) written in Swift 2.x.
Question
Everything (debugging etc.) works fine in xcode7, however when moving to xcode8 and updating the modules to use swift2.3 I was unable to debug the modules.
LLDB reported these errors:
warning: Swift error in module XYZ.
Debug info from this module will be unavailable in the debugger.
error: in auto-import:
failed to get module 'ABC' from AST context
This does not happen if I link the modules to an app built in Swift 2.3.

For me it was just as simple as it was painful and time consuming:
import SDWebImage was the PROBLEM,
because one of the frameworks had the SDWebImage already packed in it(and I couldn't see it), and that framework happened to be Objective-C, and the app was Swift.
I also added the SDWebImage to the project, because I use it in the classes I write, and that what created the mess the Xcode debugger couldn't deal with.
So basically, make sure you don't have ANYTHING duplicated in ANY way, I'd check for common things like SDWebImage for example.

use fr v instead po for debugging
For more debugging
https://www.codeproject.com/Articles/1181358/Debugging-with-Xcode

I discussed this issue with an Apple engineer named Sean at WWDC 2017.
My team spent weeks trying to figure this out, and it ended up being a bug on Apple's compiler, which we could never have figured out by ourselves. Also, it has a VERY easy workaround.
There happens to be a bug with the way the compiling flags get aggregated from the frameworks and the project, and the "pure Objective-C" project "activates" it.
Solution: add one single, empty Swift file ("Whatever.swift", or whatever) in your Objective-C project, making it not-pure-objective-c anymore (new->file->Swift file, don't create the bridging header. The file will only contain the import of Foundation).
And that's it. Problem solved.

tl:dr
Add a user defined setting under "Build Settings" for your app target.
SWIFT_VERSION = 2.3
More Info
I'm unsure if this is an Xcode 8 bug or if it's Apple policy (to try an force developers to Swift 3.0?). But... by default Xcode 8 installs the Swift 3.0 versions of the standard Swift runtime libraries.
When it comes to debugging with LLDM the Swift 2.3 modules fail to load (in to the Swift 3.0 runtime).
Forcing the app to use Swift 2.3 (or legacy Swift as Apple call it), fixes the issue.
Swift apps have this setting exposed by Xcode but you have to manually add it for an Objective-C app.
Further Advice
Port your Swift 2.3 code to Swift 3.0 as soon as possible, Apple won't support 2.x for very long.

In my case, I had to remove Objective-C Bridging header from build settings file. My Bridging header file did not do anything.. so it was okay.

I ran into the error in auto-import: failed to get module 'XYZ' from AST context message while attempting to debug in an 9.3 simulator. Switching to a 10.2 simulator resolved the issue.

I ran into this when building a framework with Carthage. Trying to debug would print the error, which referenced an Obj-C framework dependency.
I found this blog post which suggested adding a the following user-defined build setting to my project:
For Debug: REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES = NO
For Release: REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES = YES
This fixed the issue for me.

Try to restart Xcode. In my case it resolved an issue.

In my case there was a compiler error in the "C" code which was reported in LLDB, after fixing the error LLDB started working again.

As suggested by Tim https://stackoverflow.com/a/41876400/1840269 the root cause to our problem was a matter of duplicates.
We had a obj-c wrapper category for SDWebImage that was used from both obj-c and Swift.
When Importing the category from Swift everything blew up because of redefinition/duplicate import since the SDWebImage pod already exposed it self as a Swift module.
The solution? We re-implemented the obj-c category as a Swift extension - and kept using it from both Swift and obj-c by adding #objc in front of the extension and importing the #import "product-Swift.h" file from obj-c.
And maybe start with checking: https://developer.apple.com/library/content/qa/qa1947/_index.html.

I just took 2 days for me to resolve and debugging through print command all the time. Now I got the issue:
My project is in Swift and I was using objective-C library same as imported in pods for swift(old Objective-C project merged in this one) and was using import IQKeyboardManager as well as import "IQKeyboardManager.h" header as well. That conflicts and deleting the header one resolved my issue finally.
You can check with this type of duplicity in libraries.

Related

How to exclude standard but unused libswift*.dylib's from macOS app bundle and reduce bundle size

When I build my simple menubar cocoa application written in Swift 4 with Xcode 9, a lot of libswift*.dylib libraries are linked/downloaded/embedded into .app bundle,into Frameworks folder as seen below:
I am only using import Cocoa and import Foundation in my project, and some #objc functions as selector to timer functions. I really don't think my very simple menubar app would need some 3D rendering Metal library functions or any SwiftOnoneSupport, so I would like them to be removed from the .app bundle. (Same libraries are also included in the helper app for launch at login feature, which makes even the helper app over 10 MB)
I would have thought Xcode would just copy whatever is neccessary by default actually. Some similar questions were asked here and here but I don't think there is a fulfilling and up-to-date answer to both.
What I have tried so far
I set ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to NO in Build Settings. It doesn't seem to have any effect.
I set LINK_WITH_STANDARD_LIBRARIES to NO in Build Settings. It ruined everything and couldn't make it build even though I tried to add some frameworks(Cocoa, Foundation) on my own under Linked Frameworks and Libraries section.
Simply put, it's not possible to exclude the standard libraries that Swift automatically includes with an app and expect it to work. Currently any application created with Swift bundles its own version of the Swift Dynamic Library. Swift doesn’t live on the OS, rather it lives within each app bundle. What this means is that any app that is using Swift 4.1 for example bundles in the Swift 4.1 Dynamic Library (containing the 4.1 ABI), and so forth.
One of the things on the Swift project roadmap is to eventually have ABI Stability. If Swift becomes ABI Stable, Swift will live within the OS and it’s ABI will be compatible with every version of Swift.
From iOS v12.2 ABI[About] Stability for iOS is on. That is why your target will not include Swift standard library[About] because it is a part of OS

Swift had fatal errors constructing the ast context for this module

I upgraded my project to Swift 2 in Xcode 7 beta (7A120f) and get this error when trying to po self at the lldb prompt:
warning: Swift error in module myApp:
Swift had fatal errors constructing the ast context for this module: cannot load underlying module for 'UIKit'
Debug info from this module will be unavailable in the debugger.
I'm then left with a crippled debugger (no values). This happens regardless of where I place a breakpoint. I've tried:
clearing derived data
Product > Clean
restarting xcode
restarting mac
I'm able to create a new project and see debug output in it, so this probably has something to do with how my project was migrated by xcode.
What is the ast context and how can I correct it?
Edit: ast is 'Abstract Syntax Tree'. Still no idea how to fix it though.
I'm having the same issue in my project. The error that lldb spits out when attempting to po an object highlights the issue:
(lldb)po fileURL
warning: Swift error in module <APP_NAME>:
Swift had fatal errors constructing the ast context for this module: <module-includes>:1:9: note: in file included from <module-includes>:1:
#import "Headers/Crashlytics.h"
^
<APP_PATH>/Pods/Crashlytics/Crashlytics.framework/Headers/Crashlytics.h:10:9: error: include of non-modular header inside framework module 'Crashlytics'
#import <Fabric/FABAttributes.h>
^
The Crashlytics.h umbrella header in Crashlytics.framework is importing Fabric/FABAttributes.h, which is not part of the Crashlytics module (i.e. not in its module.modulemap). This is Crashlytics 3.1.0 installed using CocoaPods.
Why Xcode 7 treats this as a fatal error is beyond me (it was just a warning in 6). In Xcode 6 you could work around this sort of "non-modular header include" by enabling the "Allow Non-modular includes in Framework Modules" (CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES) build setting in your application target.
I've had no luck getting the Xcode 7 betas to honor the above flag (rdar://22044453 <-- please dup).
The only solution I've found to get the debugger working is to remove the Crashlytics pod. I comment out the Crashlytics and Fabric pods, run pod install, resume debugging and then reinstall the pods before a release.
I really hope this is fixed in Xcode 7 by the time it comes out of beta.
Check your bridging header and if you have
#import Crashlytics;
(or any other frameworks that cause the error. In my case it was GoogleMobileAds)
try replacing with
#import <Crashlytics/Crashlytics.h>
To fix this I manually migrated all my files and settings to a new xcode project. Nothing else worked. There is probably a better fix but I couldn't spend any more time looking for it.
I had the same issue.
In the most cases this issues appears when you use objective-c frameworks or libraries in Swift project.
The issue was fixed by importing objective-c frameworks or libraries in Bridging-Header only.
#import <SampleFramework/SampleFramework.h>
and remove all imports of this framework from Swift files
import SampleFramework // <-- Remove it
Then Clean and Build.
Make sure that you did this procedure for all objective-c frameworks or libraries in your projects.
Hope this helps!

Using Cocoapods in embedded framework with Xcode 6 GM

Here's my configuration :
Pod X : Linked with MyProjectSharedCode, declares class SomeClass (in Objective C)
MyProjectExtension : Today extension, sharing data with MyProject
MyProject : Companion app to configure MyProjectExtension
MyProjectSharedCode : Embedded framework for common code in MyProject and MyProjectExtension. Uses SomeClass.
I can't get it working. I've tried :
Importing PodX.hin MyProjectSharedCode.h, but it results in a compiler error :
include of non-modular header inside framework module
Which lead me to a few Stackoverflow links, including this one. However, changing this option didn't allow me to compile either. As #NachoSoto says in the accepted answer's last comment, the answer doesn't seem to work since Xcode 6 B5.
Any help/leads would be much appreciated.
There's a good post that came out today about using the development branch of Cocoapods 0.36.0 which is where frameworks/swift support is being added.
http://swiftwala.com/cocoapods-is-ready-for-swift/
Baring that I've been linking pods into a framework and then including the headers in the bridging header. Its a little wacky but it works so long as you don't want to write swift that uses the pods in the framework itself.
Edit
The pre-release version of 0.36.0 is out you can see the blog post here.

unable to print object ('po') in xcode6 beta 6 osx swift project: (Error in auto-import: failed to get module '__ObjC' from AST context)

An attempt to print object (po command) in xcode 6 beta 6 OSX Swift project results in this error message:
(lldb) po managedObject
error: Error in auto-import:
failed to get module '__ObjC' from AST context
In this case the object in question is an instance of NSManagedObject.
Any advice on how to help auto-import in getting __ObjC module into LLVM Abstract Syntax Tree context?
As of Xcode 6.1 if you attempt the po command twice it will work on the second attempt. The first po command will always fail for each new debugging session but subsequent calls work.
Have same issue in xcode 7.3.1:
error: Error in auto-import:
failed to get module 'Touch' from AST context:
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2/libxml/tree.h"
^
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2/libxml/tree.h:17:10: error: 'libxml/xmlversion.h' file not found
#include <libxml/xmlversion.h>
^
could not build Objective-C module 'LibXML2'
But you can use fr v managedObject instead of po managedObject.
I'd recommend double-checking that you have the
-D DEBUG
flag set under 'Other Swift Flags' for the scheme that you're using to debug. I experienced similar issues when I'd accidentally deleted it.
A clean of my project and deleting DerivedData worked for me.
I discussed a similar error message with an Apple engineer at WWDC2017. It seems like this issue can have many causes, and I am aware that mine is slightly different than the one described above.
My team spent weeks trying to figure this out, and it ended up being a bug on Apple's compiler, which we could never have figured out by ourselves. Also, it has a VERY easy workaround.
So, this is just me posting the fix here, in order to maximize the probability that someone else does a search for this confusing error message, and finds this answer.
So, here it is. In our case, we had an Objective-C project using a mix of Swift and Objective-C frameworks. This fix might apply in slightly different contexts, just try it.
There happens to be a bug with the way the compiling flags get aggregated from the frameworks and the project, and the "pure Objective-C" project "activates" it.
Solution: add one single, empty Swift file ("Whatever.swift", or whatever) in your Objective-C project, making it not-pure-objective-c any more (new->file->Swift file, don't create the bridging header. The file will only contain the import of Foundation).

How to access iokit/pwr_mgt from swift?

I'm trying to write an OSX app (not iOS) that prevents the system from going to sleep when certain things are happening. To do so, I'm trying to access the pwr_mgt submodule of IOKit from a MacOS app using Swift.
In XCode, I've indicated that I want to use the IOKit framework, and in code, I'm have declared import IOKit. Although IOKit's classes/methods import fine (I can see them with auto-complete when I type IO*Whatever), the ones relating to power management don't show up.
I've tried to instead import IOKit.pwr_mgt, but the compiler complains that the submodule can't be found.
<unknown>:0: error: missing required module 'pwr_mgt'
From other documentation for how to do this with Objective-c, the classes that I need to access (amongst others) are:
IOPMAssertionCreateWithName
IOPMAssertionID
IOPMAssertionRelease
CFStringRef
CFSTR
I'm not sure if there is a solution to this problem in older Xcode betas, but on Beta 7 (and I imagine in Xcode 6.1 too)
import IOKit.pwr_mgt
works fine in newer betas.

Resources