How to fix 'Cannot override a self return type with a non-self return type' after upgrading Xcode

1.3k Views Asked by At

I'm trying to build an iOS AWS app and I'm having some problems.

I just updated Xcode to version 10.2 and created a brand new project. I'm at the point where I'm trying to install the dependencies with CocoaPods for user authentication. After modifying my podfile to include AWSMobileClient (and running pod install --repo-update as the AWS documentation says) I get a build error in the AWSMobileClient.swift in this function:

@objc override public class func sharedInstance() -> AWSMobileClient {
   return _sharedInstance
}

The error says this:

Cannot override a Self return type with a non-Self return type

I'm pretty darn stuck here and the only thing I can think to do at this point is to go back to Xcode 10.1.

Any help would be greatly appreciated.

3

There are 3 best solutions below

5
On

As the error indicates, you need to return Self here if the class is not final.

@objc override public class func sharedInstance() -> Self { return _sharedInstance }

(This is assuming that _sharedInstance is of type Self.)

Alternately, you can modify the superclass not to return Self, and instead return a specific type (likely its own type).

@objc public class func sharedInstance() -> TheActualClass { return _sharedInstance }

(All subclasses will in this case need to also return TheActualClass. I assume that class is AWSMobileClient.)

Since this is a framework, I would expect this to be fixed by the vendor, and I would make sure you're running the most up to date version of the framework.

Self indicates that this method returns a value of the type of the class being called. So if you have SomeClass.sharedInstance() is must return a SomeClass. But if you subclass that, then a call to SubClass.sharedInstance() must return a SubClass. If you can't achieve that, you're going to need to make something final, or not return Self.

This is a very strange override, however. It's not clear what this code is trying to achieve.

0
On

We ran into this issue but were hesitant to edit the AWSMobileClient directly.

Setting the Swift Language version to 4.2 for the Project and Targets as well as specifying in the Pod file:

post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '4.2'
        end
    end
end

Worked for us to allow building again. As its a Swift 5 compatibility issue:

SR-695:

In Swift 5 mode, a class method returning Self can no longer be overridden with a method returning a non-final concrete class type. Such code is not type safe and will need to be updated.

2
On

As a temporary solution make the class of the method final. For example AWSMobileClient now is:

public class AWSMobileClient: _AWSMobileClient {

Change on this:

public final class AWSMobileClient: _AWSMobileClient {

And then wait for AWS fixes.