37

Let's say I define a generic class in Swift, similar to the following:

class MyArray<T> {
    func addObject(object: T) {
        // do something... hopefully
    }
}

(I know there is a slightly better implementation of array, this is merely an example.)

In Swift I can now use this class very easily:

let a = MyArray<String>()
a.addObject("abc")

With Xcode 7, we now have generics in Objective-C, so I would assume that I could use this class in Objective-C:

MyArray<NSString*> *a = [[MyArray<NSString*> alloc] init];
[a addObject:@"abc"];

However, MyArray is never added to my Project-Swift.h file. Even if I change it to inherit from NSObject, it still doesn't appear in my Swift.h file.

Is there any way to create a generic Swift class and then use it in Objective-C?


Update: If I try to inherit from NSObject and annotate with @objc:

@objc(MyArray)
class MyArray<T>: NSObject {
    func addObject(object: T) {
        // do something... hopefully
    }
}

I get the following compiler error:

Generic subclasses of '@objc' classes cannot have an explicit '@objc' attribute because they are not directly visible from Objective-C.

Does this mean there is no way to use a generic Swift class in Objective-C?

How does one indirectly reference the class?

2
  • Did you annotate your class with an @objc? Commented Sep 4, 2015 at 22:02
  • @MrBeardsley I just tried it and it gave an interesting compiler error (see above). Commented Sep 4, 2015 at 23:29

2 Answers 2

31

Swift generic types cannot be used in Objective-C.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-ID136

This excludes Swift-only features such as those listed here:

  • Generics
  • ...
Sign up to request clarification or add additional context in comments.

4 Comments

Was that document updated for Xcode 7? Since there are now generics in Objective-C, wouldn't it not be considered a Swift-only feature?
@Senseful: Lightweight generics in Objective-C are different from and much more limited than Swift generics.
@newacct do you know a webpage that describes the limitations?
The list of Swift-only exclusions is removed in the documentation for Swift 2.2.
9

There is a workaround for some situations, when you need to import Swift generic class into Objective-C.

Let's say you have Swift REST service, which uses Generics. I'm using Moya framework and that's how my service looks like:

 class AuthService: BaseService<AuthAPI> {
    func register(email: String)  {
       // ... 
    }
 }

It's inherited from base service using generics, so I can not use it directly in my Objective-C code.

So here is a workaround:

Lets create AuthServiceProtocol:

@objc protocol AuthServiceProtocol {
    func register(email: String)
}

Then let's create a factory for service (or a singleton method, no difference):

@objc class Services: NSObject {
    static let authService: AuthServiceProtocol = AuthService()
}

Then I'm able to call my generic Swift auth service from Objective-C code:

- (void)someObjcMethod {
    [Services.authService registerWithEmail:self.email];
}

3 Comments

I successfully call the Services in my obj-c class But it gives error when i tried to use authService. "Property 'authService' not found on object of type 'Services ". Plese help me out to solve this issue
Do you have to do class AuthService: BaseService<AuthAPI>, AuthServiceProtocol ?
what if a registerWithEmail wants to return some kind of generic class :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.