You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi Rio 10.3.3创建ASAuthorizationController实例报错求解决方案

解决Delphi Rio中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 10:47:40