BUILD_LIBRARY_FOR_DISTRIBUTION and IBOutlet property cannot have non-'objc' class type

This is a build error with XCode Beta 4, Swift, and framework targets with BUILD_LIBRARY_FOR_DISTRIBUTION set to yes so I can build an XCFramework. I'm seeing if anyone else has seen this and can help me out.


When BUILD_LIBRARY_FOR_DISTRIBUTION to No, then everything can build and archive just fine. When BUILD_LIBRARY_FOR_DISTRIBUTION is Yes I get a bunch of these errors:


  • @IBOutlet property cannot have non-'@objc' class type 'UIImageViewSubclass'
  • Method cannot be marked @IBAction because the type of the parameter cannot be represented in Objective-C


The only thing I can see in common with all the failures is that each class is itself a subclass of another, and that other class is a direct subclass of a UIKit object. Ones that are direct subclasses do not give the error.


So this works (one level):

@IBDesignable open class MyLabel: UILabel


// Compiles fine

@IBOutlet weak var confirmPasswordErrorLabel: MyLabel!


This fails (two levels):

@IBDesignable open class MyImageView: UIImageView

open class MyCardImageView: MyImageView


// Emits an error when BUILD_LIBRARY_FOR_DISTRIBUTION is Yes

@IBOutlet weak var cardImageView: MyCardImageView!

Replies

After more trial and error, I find it is not directly related to more than one subclass. It is related to subclassing something from an external framework and then using it.


This is a case of defining a class in one framework and subclassing it in another. This example has 2 frameworks: "Framework 1" and "Framework 2".


First I define a subclass in Framework 1.

// Defined in Framework 1
open class ImageSubclass: UIImageView {
}


Then I use it in Framework 1.

// Used in Framework 1.  This compiles.
class MyViewController: UIViewController {
    @IBOutlet weak var imageView: ImageSubclass!
}


I switch to Framework 2 and use that class in an outlet. This also works.

// Used in Framework 2.  This compiles
class MyOtherViewController: UIViewController {
    @IBOutlet weak var imageView: ImageSubclass!
}


Still in Framework 2, I subclass what I defined in Framework 1.

// Subclass in Framework 2.
open class BetterImageSubclass: ImageSubclass {
}


Then I use that subclass in an outlet. This gives me the error you can see on line 3's comment.

// Use new subclass in Framework 2.
class MyBetterOtherViewController: UIViewController {
    // Error: @IBOutlet property cannot have non-'@objc' class type 'BetterImageSubclass'
    @IBOutlet weak var imageView: BetterImageSubclass!
}


So I can't see why using it directly makes it think it is an Objective-C class (which it is), and then subclassing it makes it NOT be an Objective-C class (which is still is).


Interestingly, if I do this I get "Explicit '@objc' on subclass of 'ImageSubclass' requires iOS 13.0.0". So this is not an option either.

@objc open class BetterImageSubclass: ImageSubclass {
}
  • Is there a solution?

Add a Comment

It looks like this is iOS 13 only. When switching all projects to that as a target, the errors went away. So we'll have to stay with the lipo and friends solution for the time being.

I meet the error '@objc' static property in extension of subclass of 'SideMenuManager' requires iOS 13.0.0 after I changed BUILD_LIBRARY_FOR_DISTRIBUTION=YES.

What I've done is to extend the framework that I just made swiftmodule with a @objc static property.

I get it that it's an iOS 13 feature. My question is like what is mentioned in this original post: why I manged to compile my app before I make the framework swift module, while it fails after I do that?