扩展性 - iOS

更改每个元素的呈现

开发人员可以自定义呈现的 AdaptiveCards 元素(如 TextBlock)的外观。 以下示例演示如何更改 NumberInput 的背景色。

ACRRegistration *registration = [ACRRegistration getInstance];
// register custom renderer with registration
// custom renderer must implement ACRIBaseCardElementRenderer protocol
// for more information, please refer to CustomInputNumberRenderer.mm
 [registration setBaseCardElementRenderer:[CustomInputNumberRenderer getInstance] cardElementType:ACRNumberInput];
 ...
/// CustiomInputNumberRenderer.mm
- (UIView *)render:(UIView<ACRIContentHoldingView> *)viewGroup
              rootViewController:(UIViewController *)vc
              inputs:(NSArray *)inputs
     baseCardElement:(ACOBaseCardElement *)acoElem
          hostConfig:(ACOHostConfig *)acoConfig
  {
      ACRInputNumberRenderer *defaultRenderer = [ACRInputNumberRenderer getInstance];
 
      UIView *input = [defaultRenderer render:viewGroup
                           rootViewController:vc
                                       inputs:inputs
                              baseCardElement:acoElem
                                   hostConfig:acoConfig];
      if(input)
      {   
          // customize background color of input
          [input setBackgroundColor: [UIColor colorWithRed:1.0
                                                     green:59.0/255.0
                                                      blue:48.0/255.0
                                                     alpha:1.0]];
      }
      return input;
  }

其他属性

开发人员还可以将其他属性作为 json 有效负载的一部分发送。 例如,除了 BaseCardElement 的 json 有效负载的"间距"和"id"外,还可以将 TextBlock 角的半径添加到其 json 有效负载。 其他属性作为 NSData 和 accessbile 从 和 ACOBaseCardElement 返回 ACOBaseActionElement。 NSData 应反初始化为 NSDictionary 以访问。

"type":"TextBlock",
...
"radius":20,
...

Objective-C 示例

        NSData *additionalProperty = [acoElem additionalProperty];
         if(additionalProperty) {
             NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:additionalProperty options:NSJSONReadingMutableLeaves error:nil];
             radiusForMyTextBlock = dictionary[@"radius"];
         ...

Swift 示例

if let props = acoElem.additionalProperty() {
            if let dictionary = try JSONSerialization .jsonObject(with: props, options: JSONSerialization.ReadingOptions.mutableLeaves) as? [NSString: Any]{
                let radius = (dictionary["radius"] as! NSNumber).floatValue
            }       

自定义分析

开发人员还可以自定义分析,将新的 UI 元素添加到进度栏等活动卡中。 有关详细信息,CustomProgressBarRenderer.mm 查看详细信息。 自定义分析器必须实现 ACOIBaseCardElementParser 协议。 deserializeToCustomElement 方法应分析给定作为 NSData 的 json 有效负载,并返回指向将添加到 AdaptiveCard 呈现对象的 UIView 对象的指针。

      CustomProgressBarRenderer *progressBarRenderer = [[CustomProgressBarRenderer alloc] init];
      [registration setCustomElementParser:progressBarRenderer];

资源解析程序

AdaptiveCards 呈现器用户可以使用资源解析程序在图像加载中拥有更多控制权。

  1. 创建 ACOResourceResolvers
  2. 创建 ADCResolver
  3. 根据 URL 方案将 ADCResolver 注册到 ACOResourceResolvers;方案可以是任何字符串。
  4. 使用 ACOResourceResolvers 调用 ACOHostConfig 的 fromJson 方法
        ACOResourceResolvers resolvers = [[ACOResourceResolvers alloc] init];
        ADCResolver *resolver = [[ADCResolver alloc] init];
        [resolvers setResourceResolver:resolver scheme:@"http"];
        [resolvers setResourceResolver:resolver scheme:@"https"];
        [resolvers setResourceResolver:resolver scheme:@"data"];
        // register a custom scheme bundle with resolver
        [resolvers setResourceResolver:resolver scheme:@"bundle"];
        ACOHostConfigParseResult *hostconfigParseResult = [ACOHostConfig fromJson:hostConfig
                                                            resourceResolvers:resolvers];

ADCResolver

  • 采用 ACOIResourceResolver 协议
  • AdaptiveCards 呈现器通过 询问 UIImageView (UIImageView *)resolveImageViewResource:(NSURL *)url。 ADCResolver 可以使用空的 UIImage 或 UIImageView 和 UIImageView 来接管 UIImageView。
  • 如果 UIImage 为空,当 UIImage 设置为解析程序中的 UIImageView 时,呈现器将通过 KVO 和触发器布局更新收到通知。
  • 简单 objective-c 示例
- (UIImageView *)resolveImageViewResource:(NSURL *)url
{
    __block UIImageView *imageView = [[UIImageView alloc] init];
    // check if custom scheme bundle exists
    if ([url.scheme isEqualToString:@"bundle"]) {
        // if bundle scheme, load an image from sample's main bundle
        UIImage *image = [UIImage imageNamed:url.pathComponents.lastObject];
        imageView.image = image;
    } else {
        NSURLSessionDownloadTask *downloadPhotoTask = [[NSURLSession sharedSession]
            downloadTaskWithURL:url
              completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
                  // iOS uses NSInteger as HTTP URL status
                  NSInteger status = 200;
                  if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
                      status = ((NSHTTPURLResponse *)response).statusCode;
                  }
                  if (!error && status == 200) {
                      UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
                      if (image) {
                          dispatch_async(dispatch_get_main_queue(), ^{
                              imageView.image = image;
                          });
                      }
                  }
              }];
        [downloadPhotoTask resume];
    }
    return imageView;
}