Forward declare a Swift class to use it in an Objective-C header
Asked Answered
U

1

8

I'm trying to import a Swift class into an Objective-C header file. I know that Project-Swift.h bridge can only be imported into implementation files (.m) but I've got an Objective-C header that needs to declare a property that's defined in Swift.

I read somewhere that this can be done by forward declaring the class in the header file and importing Project-Swift.h into the implementation file. When I do this, the errors are resolved, but I can't access any class properties.

Example:

// Square.swift

@objc class Square: NSObject {
  var width: Int?
  var height: Int?
}

// Shapes.h

@class Square;

@interface Shapes: NSObject {
  @property(nonatomic, strong) Square *square;
}

// Shapes.m

#import "Shapes.h"
#import "Product-Swift.h"

@implementation Shape

@end

// Somewhere else in the code

Shapes *shapes = [Shapes new];
NSLog(@"%@", @(shapes.square.width)); <-- Property 'width' not found on object of type 'Square *'

Anyone can offer an advice on how to access the Swift class and its properties ?

Unessential answered 30/12, 2017 at 5:44 Comment(2)
Please follow these link it will work definitely #24102604Utas
That answer does not cover the forward declaration problem.Comprehend
T
0

Years later, there still seems to be no solution from Apple to provide such a forward-declaration. There is a work-around, though: declare properties on the Objective-C class in a Swift extension, and make use of associated objects.

For example:

import ObjectiveC

// Only the _address_ of this variable is going to be needed.
private var squareHandle: UInt8 = 0

extension Shapes {
    var square: Square {
        get {
            if let instance = objc_getAssociatedObject(self, &squareHandle) as? Square {
                // Already have an instance, use that.
                return instance
            }

            // Here, we want a non-optional can use default initialization.
            // Create a new instance.
            let instance = Square()
            objc_setAssociatedObject(self, &squareHandle, instance, .OBJC_ASSOCIATION_RETAIN)
            return instance
        }

        set {
            objc_setAssociatedObject(self, &squareHandle, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}
Thornburg answered 8/2 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.