使用Xamarin为一些外部代码创建绑定库时,我遇到了一个问题,尽管(据我所知)实现了协议中的所有选择器,但在Obj-C代码中,我的委托未能通过conformsToProtocol
检查,因此代码不起作用。
以下是Objective-C头文件的样子(https://github.com/janrain/jump.ios/blob/master/Janrain/JRCapture/Classes/JRCapture.h):
@protocol JRCaptureDelegate <NSObject>
@optional
- (void)engageAuthenticationDialogDidFailToShowWithError:(NSError *)error;
- (void)engageAuthenticationDidCancel;
- (void)engageAuthenticationDidSucceedForUser:(NSDictionary *)engageAuthInfo forProvider:(NSString *)provider;
- (void)engageAuthenticationDidFailWithError:(NSError *)error forProvider:(NSString *)provider;
- (void)captureSignInDidSucceedForUser:(JRCaptureUser *)captureUser
status:(JRCaptureRecordStatus)captureRecordStatus;
- (void)captureSignInDidFailWithError:(NSError *)error;
- (void)registerUserDidSucceed:(JRCaptureUser *)registeredUser;
- (void)registerUserDidFailWithError:(NSError *)error;
- (void)refreshAccessTokenDidSucceedWithContext:(id <NSObject>)context;
- (void)refreshAccessTokenDidFailWithError:(NSError *)error context:(id <NSObject>)context;
@end
这是ApiDefinition.cs
中与之相对应的部分:
[Model, BaseType (typeof (NSObject))]
public partial interface JRCaptureDelegate {
[Export ("engageAuthenticationDidCancel")]
void EngageAuthenticationCancelled ();
[Export ("engageAuthenticationDidSucceedForUser:forProvider:")]
void AuthenticationSucceededForProvider (NSDictionary engageAuthInfo, string provider);
[Export ("captureSignInDidSucceedForUser:status:")]
void SignInSucceeded (JRCaptureUser captureUser, JRCaptureRecordStatus captureRecordStatus);
[Export ("registerUserDidSucceed:")]
void RegisterUserSucceeded(JRCaptureUser registeredUser);
[Export ("refreshAccessTokenDidSucceedWithContext:")]
void RefreshAccessTokenSucceeded(NSObject context);
//- (void)engageAuthenticationDialogDidFailToShowWithError:(NSError *)error
[Export ("engageAuthenticationDialogDidFailToShowWithError:")]
void DialogFailedToShow (NSError error);
//- (void)engageAuthenticationDidFailWithError:(NSError *)error forProvider:(NSString *)provider;
[Export("engageAuthenticationDidFailWithError:forProvider:")]
void AuthenticationFailedForProvider (NSError error, NSString provider);
//- (void)captureSignInDidFailWithError:(NSError *)error;
[Export("captureSignInDidFailWithError:")]
void SignInFailed (NSError error);
//- (void)registerUserDidFailWithError:(NSError *)error;
[Export("registerUserDidFailWithError:")]
void RegisterUserFailed (NSError error);
//- (void)refreshAccessTokenDidFailWithError:(NSError *)error context:(id <NSObject>)context;
[Export("refreshAccessTokenDidFailWithError:context:")]
void RefreshAccessTokenFailed (NSError error, NSObject context);
}
除了我遇到了一个特定方法的问题,该方法似乎不想调用我的委托类中的方法之外,它的编译和工作似乎都很好。经过大量的挖掘(并通过艰苦的方式学习Objective-C),我相信我已经解决了这个问题。在我装订的图书馆里,我有这个:
if ([delegate conformsToProtocol:@protocol(JRCaptureDelegate)] &&
[delegate respondsToSelector:@selector(captureSignInDidSucceedForUser:status:)])
经过一点DLog
ing,我发现我的代理未通过conformsToProtocol
检查(尽管它确实通过了respondsToSelector
检查)。
那么,当conformsToProtocol
实现了协议中的所有方法时,为什么我的类会失败呢。我在这里错过了什么?
我的类实现了传递给采用JRCaptureDelegate
的各种方法的委托,它看起来像这样:
public class SignIn : JRCaptureDelegate
{
// overrides for each method
}
好吧,我想我可能已经破解了它。我把Adopts
属性添加到了我的类中(在Xamarin文档的各个地方都含糊地提到了这个属性,但在创建绑定库时并没有真正建议这样做)。所以现在我有了这个:
[Adopts("JRCaptureDelegate")]
public class SignIn : JRCaptureDelegate
{
// overrides for each method
}
现在它通过了conformsToProtocol
检查。我不知道为什么这不是自动的,因为我正在实现JRCaptureDelegate接口/协议。