Delphi Rio 10.3.3创建ASAuthorizationController实例报错求解决方案
我之前也遇到过类似的OC原生类封装问题,你的报错原因很明确:ASAuthorizationController根本没有公开无参的init方法,它的指定初始化方法是initWithAuthorizationRequests:,而Delphi默认的Create构造函数会对应OC的无参init,所以调用TASAuthorizationController.Create时,系统找不到对应的方法,就会抛出unrecognized selector错误。
下面是具体的解决步骤和代码示例:
1. 正确封装ASAuthorizationController类
首先要在Delphi中正确映射OC类的结构,重点是实现它的指定初始化方法:
interface uses Macapi.ObjectiveC, iOSapi.Foundation, iOSapi.AuthenticationServices; type // 先定义授权请求的接口(如果需要扩展方法可以补充) ASAuthorizationRequest = interface(IObjectiveC) ['{YOUR-GUID-HERE}'] end; // 封装ASAuthorizationController TASAuthorizationController = class(TOCLocal) private function GetObjCClass: POCClass; inline; public // 自定义构造函数,对应OC的initWithAuthorizationRequests: constructor CreateWithRequests(const Requests: TArray<ASAuthorizationRequest>); // 补充你需要的其他方法,比如presentAnimated procedure presentAnimated(animated: Boolean); // 设置代理 procedure setDelegate(delegate: ASAuthorizationControllerDelegate); end; implementation { TASAuthorizationController } constructor TASAuthorizationController.CreateWithRequests(const Requests: TArray<ASAuthorizationRequest>); var NSReqArray: NSArray; I: Integer; begin // 把Delphi数组转换为OC的NSArray NSReqArray := TNSArray.Create; try for I := 0 to High(Requests) do NSReqArray.add(Requests[I]); // 调用OC的指定初始化方法,得到实例后传给父类构造 inherited Create(GetObjCClass.initWithAuthorizationRequests(NSReqArray)); finally NSReqArray.release; end; end; function TASAuthorizationController.GetObjCClass: POCClass; begin Result := ASAuthorizationControllerClass; end; procedure TASAuthorizationController.presentAnimated(animated: Boolean); begin (GetObjectID as IASAuthorizationController).presentAnimated(animated); end; procedure TASAuthorizationController.setDelegate(delegate: ASAuthorizationControllerDelegate); begin (GetObjectID as IASAuthorizationController).setDelegate(delegate); end;
2. 正确创建并使用实例
现在你不能再用TASAuthorizationController.Create,而是要调用我们自定义的CreateWithRequests构造函数,示例如下:
var AuthController: TASAuthorizationController; AuthDelegate: TASAuthorizationControllerDelegate; AuthRequests: TArray<ASAuthorizationRequest>; AppleIDReq: ASAuthorizationAppleIDRequest; begin // 创建Apple ID授权请求 AppleIDReq := TASAuthorizationAppleIDRequest.Create; // 可以设置请求的属性,比如请求用户姓名、邮箱等 AppleIDReq.setRequestedScales(TNSArray.Wrap(TNSArray.OCClass.arrayWithObjects( ASAuthorizationFullNameScope, ASAuthorizationEmailScope, nil))); // 组装请求数组 AuthRequests := [AppleIDReq]; // 用指定构造函数创建Controller实例 AuthController := TASAuthorizationController.CreateWithRequests(AuthRequests); // 设置代理(需要你自己实现ASAuthorizationControllerDelegate接口) AuthDelegate := TMyAuthDelegate.Create; AuthController.setDelegate(AuthDelegate); // 发起授权请求 AuthController.presentAnimated(True); end;
关键知识点说明
- OC中如果类标记了指定初始化方法(就是文档里明确说明必须用这个方法初始化),就意味着它不支持无参
init,Delphi默认的Create对应无参init,所以必然报错。 - 我们通过
GetObjCClass.initWithAuthorizationRequests(...)直接调用OC类的指定初始化方法,得到OC实例指针后,传给TOCLocal的父类构造函数,这样就能正确创建对应的Delphi封装对象。 - 记得要管理好OC对象的内存(比如示例中的
NSReqArray.release),避免内存泄漏。
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

