'SessionDelegate' does not have a member named 'xxx'

家住魔仙堡 提交于 2019-12-12 02:13:21

问题


I previously asked a question on how to create a protocol with optional methods. The response was, pretty much, use Objective-c. See it here.

I did, and everything worked fine, because I was using

var delegate: SessionDelegate?;

That is, "delegate" is an optional SessionDelegate. In order to call methods from that delegate I could simply write:

self.delegate?.willOpenSession?(self);

Which was fine. But then I though, why make the delegate optional? So I changed it:

var delegate: SessionDelegate;

Obviously, the call changes too:

self.delegate.willOpenSession?(self);

The problem is, this last line (and any other of the kind) says: 'SessionDelegate' does not have a member named 'willOpenSession'. Why doesn't this work?

Here's my code:

SessionDelegate.h

@class Session;

@protocol SessionDelegate <NSObject>

@optional
- (BOOL)willOpenSession:(Session*)session;
- (void)didOpenSession:(Session*)session;
- (void)didFailOpenningSession:(Session*)session withError:(NSError*)error;

- (BOOL)willCloseSession:(Session*)session destroyingToken:(BOOL)destroyingToken;
- (void)didCloseSession:(Session*)session destroyingToken:(BOOL)destroyingToken;

@end

xxx-Bridging-Header.h

#import <Foundation/Foundation.h>
#import <FacebookSDK/FacebookSDK.h>
#import "SessionDelegate.h"

Session.swift

import Foundation

protocol Session {

    var delegate: SessionDelegate { get set };

    var isOpen: Bool { get };
    var isCached: Bool { get };

    func open();
    func close();
    func destroy();
}

FacebookSession.swift

import Foundation

class FacebookSession : Session {

    var delegate: SessionDelegate;

    var isOpen: Bool {
    get {
        return FBSession.activeSession().isOpen;
    }
    }

    // TODO
    var isCached: Bool {
    get {
        return false;
    }
    }

    init(delegate: SessionDelegate) {
        self.delegate = delegate;
    }

    func open() {

        if self.isOpen {
            return;
        }

        // Trigger the "will" event
        self.delegate.willOpenSession?(self);

        // Handle session state changes
        var completionHandler: FBSessionStateHandler = {

            session, status, error in

            if error {

                // Login failed for some reason, so we notify the delegate.
                // TODO we should turn this NSError message into something more generic (that is, not facebook specific)
                self.delegate.didFailOpenningSession?(self, withError: error);
            }

            else if status.value == FBSessionStateClosedLoginFailed.value {

                // Login failed with no error. I'm not sure this ever happens
                self.delegate.didFailOpenningSession?(self, withError: error);
            }

            else if status.value == FBSessionStateOpen.value || status.value == FBSessionStateOpenTokenExtended.value {

                // Session is now open, we should notify the delegate
                self.delegate.didOpenSession?(self);
            }

            else {

                // There's no error but the session didn't open either. I don't think this ever happens, but if it does, what should we do here?
                abort();
            }
        };

        // Open the session, prompting the user if necessary
        if FBSession.openActiveSessionWithReadPermissions([], allowLoginUI: true, completionHandler: completionHandler) {

            // If we end up here, the session token must exist, se we now have an open session
            self.delegate.d didOpenSession?(self);
        }
    }

    func close() {

    }

    func destroy() {

    }
}

Best regards.

Edit: I also tried the following

self.delegate.willOpenSession?(self as Session);

And

self.delegate.willOpenSession(self as Session);

Neither works.

Edit: After all, it doesn't work if I use

var delegate: SessionDelegate?;

Edit: The previous change also changes the error message. Now I have optional SessionDelegate (as I said in the previous edit) and the following line

self.delegate?.willOpenSession?(self)

Says: "Could not find member 'willOpenSession'"


回答1:


You're getting this error because you define Session as a protocol, but the Objective-C method definitions in the SessionDelegate protocol are expecting a Session class or subclass. In Swift you can use protocol names interchangeably with class names in method definitions, but in Objective-C there's a difference:

- (void)willOpenSession:(Session *)session;    // expects instance of Session class or subclass
- (void)willOpenSession:(id<Session>)session;  // expects object conforming to Session protocol

From the code you posted I can't tell why you've declared Session as a protocol -- does it add functionality to disparate classes? Could it instead be a superclass that FacebookSession (and presumably other sessions) simply inherits from? Changing Session to a class (and stubbing the methods) would solve the issue. Otherwise you'll need to change your SessionDelegate methods to expect an id<Session>, but for me that broke the compiler.



来源:https://stackoverflow.com/questions/24591921/sessiondelegate-does-not-have-a-member-named-xxx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!