62

I'm using Xcode 8 and Swift 3.0. What does this error message mean?

ld: warning: Some object files have incompatible Objective-C category definitions. Some category metadata may be lost. All files containing Objective-C categories should be built using the same compiler.

JAL
  • 41,701
  • 23
  • 172
  • 300
jherg
  • 1,696
  • 2
  • 13
  • 15
  • see this https://github.com/Carthage/Carthage/issues/1482 and this https://forums.developer.apple.com/thread/49618 – Anbu.Karthik Sep 23 '16 at 17:03
  • Thanks. I actually saw those before posting. No answers in them. – jherg Sep 23 '16 at 17:52
  • Have you expanded the warning message? Usually there is an icon on the far right of the line that will expand the message and let you see the command line calls and results. – Mobile Ben Sep 24 '16 at 05:33
  • @MobileBen yes, thanks. I'm not seeing anything helpful in there. – jherg Sep 26 '16 at 15:47
  • As the error message mentions compiler versions (and as I assume you have made a clean build after the upgrade to XCode 8): are you using any libraries in binary form (.a file or third-party framework) in your project? – Codo Oct 11 '16 at 10:44
  • 2
    Just got this... nothing posted here works :/ – William LeGate Dec 03 '16 at 04:04

8 Answers8

40

I also had this issue in a UIColor extension, my app is entirely made with swift except for some frameworks that use Objective-c so I have no problem in declaring the var as @nonobjc:

extension UIColor {
   @nonobjc static var lol: UIColor {
      return UIColor.red
   }
}

From the apple docs:

The nonobjc attribute tells the compiler to make the declaration unavailable in Objective-C code...

Since this code is unavailable to Objective-C the warning disappears.

juanjo
  • 3,737
  • 3
  • 39
  • 44
  • 4
    I had to add @nonobjc to all class and static variables in all extensions used in my target. Only after that warning disappeared. – slamor Dec 14 '16 at 22:24
  • Damn I tried to use a regex to find all extensions with static properties, but Xcode itself – RyanM Apr 28 '17 at 19:07
22

In my case, the reason was having computed type property in an extension:

extension NSParagraphStyle {
    class var defaultStyle: NSParagraphStyle {
        return ...
    }
}

Not sure what the exact reason behind this is, but to get rid of the warning I had to convert the computed type property (class var) to a type method (class func):

extension NSParagraphStyle {
    class func defaultStyle() -> NSParagraphStyle {
        return ...
    }
}
Hejazi
  • 16,587
  • 9
  • 52
  • 67
  • 1
    I'm trying to use an extensio to UIColor to have my own set of colors. Do they have to be functions? In previous versions of Swift you had UIColor.whiteColor(), but now it is UIColor.white. I want to have UIColor.myColor. Any idea how to achieve that? – Olav Gausaker Oct 13 '16 at 13:23
  • You can ignore the warning if you want and everything should work fine. But not sure if you can use that property from ObjC code though. – Hejazi Oct 13 '16 at 13:32
  • @Hejazi is there a way to suppress this warning? or by saying ignore the warning you mean just pretend you don't see it? – Ismail Oct 13 '16 at 13:39
  • @Ismail AFAIK, there is no way to suppress warnings in Swift. I meant you can just ignore this warning for the time being (until Apple fixes what appears to be a swift compiler bug), or use type methods instead of computed type properties as I said before. – Hejazi Oct 13 '16 at 14:00
  • 1
    I was seeing this warning and found this answer. I was skeptical that it would work for me because the warning seems to have nothing to do with the answer, but the answer fixed the warning. – Josh Adams Oct 31 '16 at 14:00
  • This was my solution as well. I had static let/var properties declared in Swift that needed to be accessed from Obj-C (marking @nonobjc wasn't an option) so I had to convert those properties to static func's. – tylermilner Apr 20 '18 at 18:07
10

This warning appeared in my project after adding a framework that used Objective-C in my application that otherwise used Swift 3 entirely.

By declaring all static functions and static variables in all extensions as @nonobjc this warning went away.

For example

extension Notification.Name {
    @nonobjc static let MyNotificationName = Notification.Name("NNSongFavoriteStatusDidChangeNotification")
}

or

extension UIColor {
    @nonobjc static let superGiantRed = UIColor(red: 180.0/255.0, green: 40.0/255.0, blue: 27.0/255.0, alpha: 1.0)
}
Groot
  • 13,943
  • 6
  • 61
  • 72
9

Google Analytics pod

In Build Settings -> Other Linker Flags if you have the -ObjC on -l"GoogleAnalytics" flag this warning will appear. I don`t know why or how to resolve, but can be your problem too.

Renato Ioshida
  • 421
  • 3
  • 6
  • 1
    @Raniys No my friend, I think this will be resolved when google update theirs repository. If you delete the -ObjC flag the warning go away, But I dont know the problems that can cause your project – Renato Ioshida Nov 30 '16 at 12:05
  • @Raniys hello my friend, i had notice that after my pod install, this warning appeared **"[!] The `project[Debug]` target overrides the `ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES` build setting defined in `podsFolder.xcconfig'. This can lead to problems with the CocoaPods installation"**. When i corrected this warning, in my build settings, the XCode warning is gone. – Renato Ioshida Mar 17 '17 at 11:46
5

In my case it was a class variable.

public extension NSObject {
    public class var nameOfClass: String{
        return NSStringFromClass(self).components(separatedBy: ".").last!
    }

Adding @nonobjc helped.

Bogdan
  • 181
  • 1
  • 5
4

For me the issue was that I was using a third-party framework from a vendor built with Xcode 7 in my Swift 3 application built with Xcode 8. Because the framework was a compiled binary, the only option I had was to ask my vendor for a new framework built with the latest version of Xcode.

JAL
  • 41,701
  • 23
  • 172
  • 300
  • Can you tell us which library it was? – allaire Nov 03 '16 at 11:59
  • @allaire It was a proprietary SDK from Adobe. – JAL Nov 03 '16 at 12:38
  • Ahh too bad. I'm facing a similar issue, but I don't have the motivation to remove pod one by one :( – allaire Nov 03 '16 at 15:01
  • 1
    @allaire This issue should only occur with pre-built frameworks. If you have the source code for any of your cocoapods (the pod is built from the source), you can rule those out, since you know they're being built with the latest version of Xcode that you are using – JAL Nov 03 '16 at 16:27
  • I suspect static libraries in Cocoapods (like Google Analytics) – allaire Nov 04 '16 at 15:17
1

I was able to solve my problem when I changed the "class var" to "class func":

There was:

class var applicationVersionNumber: String {
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        return version
    }
    return "Version Number Not Available"
}

Has become:

class func applicationVersionNumber() -> String {
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        return version
    }
    return "Version Number Not Available"
}

Source: https://forums.developer.apple.com/message/146579#146579

A.Kant
  • 2,750
  • 3
  • 19
  • 15
0

Rather than marking each member as @nonobjc individually, you can instead mark the entire extension as @nonobjc:

@nonobjc extension UIStoryboard {
  static let main = UIStoryboard(name: "Main", bundle: nil)
  static let welcome = UIStoryboard(name: "Main", bundle: nil)
}
Adam Sharp
  • 3,618
  • 25
  • 29