// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Autogenerated from Pigeon (v4.2.13), do not edit directly.
// See also: https://pub.dev/packages/pigeon
#import "FWFGeneratedWebKitApis.h"
#import <Flutter/Flutter.h>

#if !__has_feature(objc_arc)
#error File requires ARC to be enabled.
#endif

static NSArray *wrapResult(id result, FlutterError *error) {
  if (error) {
    return @[
      error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null]
    ];
  }
  return @[ result ?: [NSNull null] ];
}
static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
  id result = array[key];
  return (result == [NSNull null]) ? nil : result;
}

@interface FWFNSKeyValueObservingOptionsEnumData ()
+ (FWFNSKeyValueObservingOptionsEnumData *)fromList:(NSArray *)list;
+ (nullable FWFNSKeyValueObservingOptionsEnumData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFNSKeyValueChangeKeyEnumData ()
+ (FWFNSKeyValueChangeKeyEnumData *)fromList:(NSArray *)list;
+ (nullable FWFNSKeyValueChangeKeyEnumData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKUserScriptInjectionTimeEnumData ()
+ (FWFWKUserScriptInjectionTimeEnumData *)fromList:(NSArray *)list;
+ (nullable FWFWKUserScriptInjectionTimeEnumData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKAudiovisualMediaTypeEnumData ()
+ (FWFWKAudiovisualMediaTypeEnumData *)fromList:(NSArray *)list;
+ (nullable FWFWKAudiovisualMediaTypeEnumData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKWebsiteDataTypeEnumData ()
+ (FWFWKWebsiteDataTypeEnumData *)fromList:(NSArray *)list;
+ (nullable FWFWKWebsiteDataTypeEnumData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKNavigationActionPolicyEnumData ()
+ (FWFWKNavigationActionPolicyEnumData *)fromList:(NSArray *)list;
+ (nullable FWFWKNavigationActionPolicyEnumData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFNSHttpCookiePropertyKeyEnumData ()
+ (FWFNSHttpCookiePropertyKeyEnumData *)fromList:(NSArray *)list;
+ (nullable FWFNSHttpCookiePropertyKeyEnumData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFNSUrlRequestData ()
+ (FWFNSUrlRequestData *)fromList:(NSArray *)list;
+ (nullable FWFNSUrlRequestData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKUserScriptData ()
+ (FWFWKUserScriptData *)fromList:(NSArray *)list;
+ (nullable FWFWKUserScriptData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKNavigationActionData ()
+ (FWFWKNavigationActionData *)fromList:(NSArray *)list;
+ (nullable FWFWKNavigationActionData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKFrameInfoData ()
+ (FWFWKFrameInfoData *)fromList:(NSArray *)list;
+ (nullable FWFWKFrameInfoData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFNSErrorData ()
+ (FWFNSErrorData *)fromList:(NSArray *)list;
+ (nullable FWFNSErrorData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFWKScriptMessageData ()
+ (FWFWKScriptMessageData *)fromList:(NSArray *)list;
+ (nullable FWFWKScriptMessageData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end
@interface FWFNSHttpCookieData ()
+ (FWFNSHttpCookieData *)fromList:(NSArray *)list;
+ (nullable FWFNSHttpCookieData *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end

@implementation FWFNSKeyValueObservingOptionsEnumData
+ (instancetype)makeWithValue:(FWFNSKeyValueObservingOptionsEnum)value {
  FWFNSKeyValueObservingOptionsEnumData *pigeonResult =
      [[FWFNSKeyValueObservingOptionsEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFNSKeyValueObservingOptionsEnumData *)fromList:(NSArray *)list {
  FWFNSKeyValueObservingOptionsEnumData *pigeonResult =
      [[FWFNSKeyValueObservingOptionsEnumData alloc] init];
  pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue];
  return pigeonResult;
}
+ (nullable FWFNSKeyValueObservingOptionsEnumData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFNSKeyValueObservingOptionsEnumData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    @(self.value),
  ];
}
@end

@implementation FWFNSKeyValueChangeKeyEnumData
+ (instancetype)makeWithValue:(FWFNSKeyValueChangeKeyEnum)value {
  FWFNSKeyValueChangeKeyEnumData *pigeonResult = [[FWFNSKeyValueChangeKeyEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFNSKeyValueChangeKeyEnumData *)fromList:(NSArray *)list {
  FWFNSKeyValueChangeKeyEnumData *pigeonResult = [[FWFNSKeyValueChangeKeyEnumData alloc] init];
  pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue];
  return pigeonResult;
}
+ (nullable FWFNSKeyValueChangeKeyEnumData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFNSKeyValueChangeKeyEnumData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    @(self.value),
  ];
}
@end

@implementation FWFWKUserScriptInjectionTimeEnumData
+ (instancetype)makeWithValue:(FWFWKUserScriptInjectionTimeEnum)value {
  FWFWKUserScriptInjectionTimeEnumData *pigeonResult =
      [[FWFWKUserScriptInjectionTimeEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKUserScriptInjectionTimeEnumData *)fromList:(NSArray *)list {
  FWFWKUserScriptInjectionTimeEnumData *pigeonResult =
      [[FWFWKUserScriptInjectionTimeEnumData alloc] init];
  pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue];
  return pigeonResult;
}
+ (nullable FWFWKUserScriptInjectionTimeEnumData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKUserScriptInjectionTimeEnumData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    @(self.value),
  ];
}
@end

@implementation FWFWKAudiovisualMediaTypeEnumData
+ (instancetype)makeWithValue:(FWFWKAudiovisualMediaTypeEnum)value {
  FWFWKAudiovisualMediaTypeEnumData *pigeonResult =
      [[FWFWKAudiovisualMediaTypeEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKAudiovisualMediaTypeEnumData *)fromList:(NSArray *)list {
  FWFWKAudiovisualMediaTypeEnumData *pigeonResult =
      [[FWFWKAudiovisualMediaTypeEnumData alloc] init];
  pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue];
  return pigeonResult;
}
+ (nullable FWFWKAudiovisualMediaTypeEnumData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKAudiovisualMediaTypeEnumData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    @(self.value),
  ];
}
@end

@implementation FWFWKWebsiteDataTypeEnumData
+ (instancetype)makeWithValue:(FWFWKWebsiteDataTypeEnum)value {
  FWFWKWebsiteDataTypeEnumData *pigeonResult = [[FWFWKWebsiteDataTypeEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKWebsiteDataTypeEnumData *)fromList:(NSArray *)list {
  FWFWKWebsiteDataTypeEnumData *pigeonResult = [[FWFWKWebsiteDataTypeEnumData alloc] init];
  pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue];
  return pigeonResult;
}
+ (nullable FWFWKWebsiteDataTypeEnumData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKWebsiteDataTypeEnumData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    @(self.value),
  ];
}
@end

@implementation FWFWKNavigationActionPolicyEnumData
+ (instancetype)makeWithValue:(FWFWKNavigationActionPolicyEnum)value {
  FWFWKNavigationActionPolicyEnumData *pigeonResult =
      [[FWFWKNavigationActionPolicyEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKNavigationActionPolicyEnumData *)fromList:(NSArray *)list {
  FWFWKNavigationActionPolicyEnumData *pigeonResult =
      [[FWFWKNavigationActionPolicyEnumData alloc] init];
  pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue];
  return pigeonResult;
}
+ (nullable FWFWKNavigationActionPolicyEnumData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKNavigationActionPolicyEnumData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    @(self.value),
  ];
}
@end

@implementation FWFNSHttpCookiePropertyKeyEnumData
+ (instancetype)makeWithValue:(FWFNSHttpCookiePropertyKeyEnum)value {
  FWFNSHttpCookiePropertyKeyEnumData *pigeonResult =
      [[FWFNSHttpCookiePropertyKeyEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFNSHttpCookiePropertyKeyEnumData *)fromList:(NSArray *)list {
  FWFNSHttpCookiePropertyKeyEnumData *pigeonResult =
      [[FWFNSHttpCookiePropertyKeyEnumData alloc] init];
  pigeonResult.value = [GetNullableObjectAtIndex(list, 0) integerValue];
  return pigeonResult;
}
+ (nullable FWFNSHttpCookiePropertyKeyEnumData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFNSHttpCookiePropertyKeyEnumData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    @(self.value),
  ];
}
@end

@implementation FWFNSUrlRequestData
+ (instancetype)makeWithUrl:(NSString *)url
                 httpMethod:(nullable NSString *)httpMethod
                   httpBody:(nullable FlutterStandardTypedData *)httpBody
        allHttpHeaderFields:(NSDictionary<NSString *, NSString *> *)allHttpHeaderFields {
  FWFNSUrlRequestData *pigeonResult = [[FWFNSUrlRequestData alloc] init];
  pigeonResult.url = url;
  pigeonResult.httpMethod = httpMethod;
  pigeonResult.httpBody = httpBody;
  pigeonResult.allHttpHeaderFields = allHttpHeaderFields;
  return pigeonResult;
}
+ (FWFNSUrlRequestData *)fromList:(NSArray *)list {
  FWFNSUrlRequestData *pigeonResult = [[FWFNSUrlRequestData alloc] init];
  pigeonResult.url = GetNullableObjectAtIndex(list, 0);
  NSAssert(pigeonResult.url != nil, @"");
  pigeonResult.httpMethod = GetNullableObjectAtIndex(list, 1);
  pigeonResult.httpBody = GetNullableObjectAtIndex(list, 2);
  pigeonResult.allHttpHeaderFields = GetNullableObjectAtIndex(list, 3);
  NSAssert(pigeonResult.allHttpHeaderFields != nil, @"");
  return pigeonResult;
}
+ (nullable FWFNSUrlRequestData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFNSUrlRequestData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.url ?: [NSNull null]),
    (self.httpMethod ?: [NSNull null]),
    (self.httpBody ?: [NSNull null]),
    (self.allHttpHeaderFields ?: [NSNull null]),
  ];
}
@end

@implementation FWFWKUserScriptData
+ (instancetype)makeWithSource:(NSString *)source
                 injectionTime:(nullable FWFWKUserScriptInjectionTimeEnumData *)injectionTime
               isMainFrameOnly:(NSNumber *)isMainFrameOnly {
  FWFWKUserScriptData *pigeonResult = [[FWFWKUserScriptData alloc] init];
  pigeonResult.source = source;
  pigeonResult.injectionTime = injectionTime;
  pigeonResult.isMainFrameOnly = isMainFrameOnly;
  return pigeonResult;
}
+ (FWFWKUserScriptData *)fromList:(NSArray *)list {
  FWFWKUserScriptData *pigeonResult = [[FWFWKUserScriptData alloc] init];
  pigeonResult.source = GetNullableObjectAtIndex(list, 0);
  NSAssert(pigeonResult.source != nil, @"");
  pigeonResult.injectionTime =
      [FWFWKUserScriptInjectionTimeEnumData nullableFromList:(GetNullableObjectAtIndex(list, 1))];
  pigeonResult.isMainFrameOnly = GetNullableObjectAtIndex(list, 2);
  NSAssert(pigeonResult.isMainFrameOnly != nil, @"");
  return pigeonResult;
}
+ (nullable FWFWKUserScriptData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKUserScriptData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.source ?: [NSNull null]),
    (self.injectionTime ? [self.injectionTime toList] : [NSNull null]),
    (self.isMainFrameOnly ?: [NSNull null]),
  ];
}
@end

@implementation FWFWKNavigationActionData
+ (instancetype)makeWithRequest:(FWFNSUrlRequestData *)request
                    targetFrame:(FWFWKFrameInfoData *)targetFrame
                 navigationType:(FWFWKNavigationType)navigationType {
  FWFWKNavigationActionData *pigeonResult = [[FWFWKNavigationActionData alloc] init];
  pigeonResult.request = request;
  pigeonResult.targetFrame = targetFrame;
  pigeonResult.navigationType = navigationType;
  return pigeonResult;
}
+ (FWFWKNavigationActionData *)fromList:(NSArray *)list {
  FWFWKNavigationActionData *pigeonResult = [[FWFWKNavigationActionData alloc] init];
  pigeonResult.request = [FWFNSUrlRequestData nullableFromList:(GetNullableObjectAtIndex(list, 0))];
  NSAssert(pigeonResult.request != nil, @"");
  pigeonResult.targetFrame =
      [FWFWKFrameInfoData nullableFromList:(GetNullableObjectAtIndex(list, 1))];
  NSAssert(pigeonResult.targetFrame != nil, @"");
  pigeonResult.navigationType = [GetNullableObjectAtIndex(list, 2) integerValue];
  return pigeonResult;
}
+ (nullable FWFWKNavigationActionData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKNavigationActionData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.request ? [self.request toList] : [NSNull null]),
    (self.targetFrame ? [self.targetFrame toList] : [NSNull null]),
    @(self.navigationType),
  ];
}
@end

@implementation FWFWKFrameInfoData
+ (instancetype)makeWithIsMainFrame:(NSNumber *)isMainFrame {
  FWFWKFrameInfoData *pigeonResult = [[FWFWKFrameInfoData alloc] init];
  pigeonResult.isMainFrame = isMainFrame;
  return pigeonResult;
}
+ (FWFWKFrameInfoData *)fromList:(NSArray *)list {
  FWFWKFrameInfoData *pigeonResult = [[FWFWKFrameInfoData alloc] init];
  pigeonResult.isMainFrame = GetNullableObjectAtIndex(list, 0);
  NSAssert(pigeonResult.isMainFrame != nil, @"");
  return pigeonResult;
}
+ (nullable FWFWKFrameInfoData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKFrameInfoData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.isMainFrame ?: [NSNull null]),
  ];
}
@end

@implementation FWFNSErrorData
+ (instancetype)makeWithCode:(NSNumber *)code
                      domain:(NSString *)domain
        localizedDescription:(NSString *)localizedDescription {
  FWFNSErrorData *pigeonResult = [[FWFNSErrorData alloc] init];
  pigeonResult.code = code;
  pigeonResult.domain = domain;
  pigeonResult.localizedDescription = localizedDescription;
  return pigeonResult;
}
+ (FWFNSErrorData *)fromList:(NSArray *)list {
  FWFNSErrorData *pigeonResult = [[FWFNSErrorData alloc] init];
  pigeonResult.code = GetNullableObjectAtIndex(list, 0);
  NSAssert(pigeonResult.code != nil, @"");
  pigeonResult.domain = GetNullableObjectAtIndex(list, 1);
  NSAssert(pigeonResult.domain != nil, @"");
  pigeonResult.localizedDescription = GetNullableObjectAtIndex(list, 2);
  NSAssert(pigeonResult.localizedDescription != nil, @"");
  return pigeonResult;
}
+ (nullable FWFNSErrorData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFNSErrorData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.code ?: [NSNull null]),
    (self.domain ?: [NSNull null]),
    (self.localizedDescription ?: [NSNull null]),
  ];
}
@end

@implementation FWFWKScriptMessageData
+ (instancetype)makeWithName:(NSString *)name body:(id)body {
  FWFWKScriptMessageData *pigeonResult = [[FWFWKScriptMessageData alloc] init];
  pigeonResult.name = name;
  pigeonResult.body = body;
  return pigeonResult;
}
+ (FWFWKScriptMessageData *)fromList:(NSArray *)list {
  FWFWKScriptMessageData *pigeonResult = [[FWFWKScriptMessageData alloc] init];
  pigeonResult.name = GetNullableObjectAtIndex(list, 0);
  NSAssert(pigeonResult.name != nil, @"");
  pigeonResult.body = GetNullableObjectAtIndex(list, 1);
  return pigeonResult;
}
+ (nullable FWFWKScriptMessageData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFWKScriptMessageData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.name ?: [NSNull null]),
    (self.body ?: [NSNull null]),
  ];
}
@end

@implementation FWFNSHttpCookieData
+ (instancetype)makeWithPropertyKeys:(NSArray<FWFNSHttpCookiePropertyKeyEnumData *> *)propertyKeys
                      propertyValues:(NSArray<id> *)propertyValues {
  FWFNSHttpCookieData *pigeonResult = [[FWFNSHttpCookieData alloc] init];
  pigeonResult.propertyKeys = propertyKeys;
  pigeonResult.propertyValues = propertyValues;
  return pigeonResult;
}
+ (FWFNSHttpCookieData *)fromList:(NSArray *)list {
  FWFNSHttpCookieData *pigeonResult = [[FWFNSHttpCookieData alloc] init];
  pigeonResult.propertyKeys = GetNullableObjectAtIndex(list, 0);
  NSAssert(pigeonResult.propertyKeys != nil, @"");
  pigeonResult.propertyValues = GetNullableObjectAtIndex(list, 1);
  NSAssert(pigeonResult.propertyValues != nil, @"");
  return pigeonResult;
}
+ (nullable FWFNSHttpCookieData *)nullableFromList:(NSArray *)list {
  return (list) ? [FWFNSHttpCookieData fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.propertyKeys ?: [NSNull null]),
    (self.propertyValues ?: [NSNull null]),
  ];
}
@end

@interface FWFWKWebsiteDataStoreHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKWebsiteDataStoreHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFWKWebsiteDataTypeEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKWebsiteDataStoreHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKWebsiteDataStoreHostApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKWebsiteDataStoreHostApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKWebsiteDataStoreHostApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKWebsiteDataStoreHostApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKWebsiteDataStoreHostApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKWebsiteDataStoreHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKWebsiteDataStoreHostApiCodecReaderWriter *readerWriter =
        [[FWFWKWebsiteDataStoreHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

void FWFWKWebsiteDataStoreHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                       NSObject<FWFWKWebsiteDataStoreHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createFromWebViewConfiguration"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebsiteDataStoreHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(createFromWebViewConfigurationWithIdentifier:
                                                                 configurationIdentifier:error:)],
          @"FWFWKWebsiteDataStoreHostApi api (%@) doesn't respond to "
          @"@selector(createFromWebViewConfigurationWithIdentifier:configurationIdentifier:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewConfigurationWithIdentifier:arg_identifier
                                  configurationIdentifier:arg_configurationIdentifier
                                                    error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebsiteDataStoreHostApi.createDefaultDataStore"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebsiteDataStoreHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createDefaultDataStoreWithIdentifier:error:)],
                @"FWFWKWebsiteDataStoreHostApi api (%@) doesn't respond to "
                @"@selector(createDefaultDataStoreWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createDefaultDataStoreWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebsiteDataStoreHostApi.removeDataOfTypes"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebsiteDataStoreHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector
               (removeDataFromDataStoreWithIdentifier:ofTypes:modifiedSince:completion:)],
          @"FWFWKWebsiteDataStoreHostApi api (%@) doesn't respond to "
          @"@selector(removeDataFromDataStoreWithIdentifier:ofTypes:modifiedSince:completion:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSArray<FWFWKWebsiteDataTypeEnumData *> *arg_dataTypes = GetNullableObjectAtIndex(args, 1);
        NSNumber *arg_modificationTimeInSecondsSinceEpoch = GetNullableObjectAtIndex(args, 2);
        [api removeDataFromDataStoreWithIdentifier:arg_identifier
                                           ofTypes:arg_dataTypes
                                     modifiedSince:arg_modificationTimeInSecondsSinceEpoch
                                        completion:^(NSNumber *_Nullable output,
                                                     FlutterError *_Nullable error) {
                                          callback(wrapResult(output, error));
                                        }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
NSObject<FlutterMessageCodec> *FWFUIViewHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

void FWFUIViewHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                           NSObject<FWFUIViewHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.UIViewHostApi.setBackgroundColor"
        binaryMessenger:binaryMessenger
                  codec:FWFUIViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(setBackgroundColorForViewWithIdentifier:
                                                                                  toValue:error:)],
                @"FWFUIViewHostApi api (%@) doesn't respond to "
                @"@selector(setBackgroundColorForViewWithIdentifier:toValue:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_value = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setBackgroundColorForViewWithIdentifier:arg_identifier toValue:arg_value error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.UIViewHostApi.setOpaque"
        binaryMessenger:binaryMessenger
                  codec:FWFUIViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(setOpaqueForViewWithIdentifier:isOpaque:error:)],
                @"FWFUIViewHostApi api (%@) doesn't respond to "
                @"@selector(setOpaqueForViewWithIdentifier:isOpaque:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_opaque = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setOpaqueForViewWithIdentifier:arg_identifier isOpaque:arg_opaque error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
NSObject<FlutterMessageCodec> *FWFUIScrollViewHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

void FWFUIScrollViewHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                 NSObject<FWFUIScrollViewHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.UIScrollViewHostApi.createFromWebView"
        binaryMessenger:binaryMessenger
                  codec:FWFUIScrollViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createFromWebViewWithIdentifier:
                                                                webViewIdentifier:error:)],
                @"FWFUIScrollViewHostApi api (%@) doesn't respond to "
                @"@selector(createFromWebViewWithIdentifier:webViewIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_webViewIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewWithIdentifier:arg_identifier
                           webViewIdentifier:arg_webViewIdentifier
                                       error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.UIScrollViewHostApi.getContentOffset"
        binaryMessenger:binaryMessenger
                  codec:FWFUIScrollViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(contentOffsetForScrollViewWithIdentifier:error:)],
                @"FWFUIScrollViewHostApi api (%@) doesn't respond to "
                @"@selector(contentOffsetForScrollViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSArray<NSNumber *> *output = [api contentOffsetForScrollViewWithIdentifier:arg_identifier
                                                                              error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.UIScrollViewHostApi.scrollBy"
        binaryMessenger:binaryMessenger
                  codec:FWFUIScrollViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(scrollByForScrollViewWithIdentifier:x:y:error:)],
                @"FWFUIScrollViewHostApi api (%@) doesn't respond to "
                @"@selector(scrollByForScrollViewWithIdentifier:x:y:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_x = GetNullableObjectAtIndex(args, 1);
        NSNumber *arg_y = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api scrollByForScrollViewWithIdentifier:arg_identifier x:arg_x y:arg_y error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.UIScrollViewHostApi.setContentOffset"
        binaryMessenger:binaryMessenger
                  codec:FWFUIScrollViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (setContentOffsetForScrollViewWithIdentifier:toX:y:error:)],
                @"FWFUIScrollViewHostApi api (%@) doesn't respond to "
                @"@selector(setContentOffsetForScrollViewWithIdentifier:toX:y:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_x = GetNullableObjectAtIndex(args, 1);
        NSNumber *arg_y = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api setContentOffsetForScrollViewWithIdentifier:arg_identifier
                                                     toX:arg_x
                                                       y:arg_y
                                                   error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FWFWKWebViewConfigurationHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKWebViewConfigurationHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFWKAudiovisualMediaTypeEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKWebViewConfigurationHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKWebViewConfigurationHostApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKWebViewConfigurationHostApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKWebViewConfigurationHostApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKWebViewConfigurationHostApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKWebViewConfigurationHostApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKWebViewConfigurationHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKWebViewConfigurationHostApiCodecReaderWriter *readerWriter =
        [[FWFWKWebViewConfigurationHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

void FWFWKWebViewConfigurationHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                           NSObject<FWFWKWebViewConfigurationHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewConfigurationHostApi.create"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewConfigurationHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createWithIdentifier:error:)],
                @"FWFWKWebViewConfigurationHostApi api (%@) doesn't respond to "
                @"@selector(createWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewConfigurationHostApi.createFromWebView"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewConfigurationHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createFromWebViewWithIdentifier:
                                                                webViewIdentifier:error:)],
                @"FWFWKWebViewConfigurationHostApi api (%@) doesn't respond to "
                @"@selector(createFromWebViewWithIdentifier:webViewIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_webViewIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewWithIdentifier:arg_identifier
                           webViewIdentifier:arg_webViewIdentifier
                                       error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.WKWebViewConfigurationHostApi.setAllowsInlineMediaPlayback"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewConfigurationHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector
               (setAllowsInlineMediaPlaybackForConfigurationWithIdentifier:isAllowed:error:)],
          @"FWFWKWebViewConfigurationHostApi api (%@) doesn't respond to "
          @"@selector(setAllowsInlineMediaPlaybackForConfigurationWithIdentifier:isAllowed:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_allow = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setAllowsInlineMediaPlaybackForConfigurationWithIdentifier:arg_identifier
                                                              isAllowed:arg_allow
                                                                  error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewConfigurationHostApi."
                        @"setMediaTypesRequiringUserActionForPlayback"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewConfigurationHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (setMediaTypesRequiresUserActionForConfigurationWithIdentifier:
                                                                           forTypes:error:)],
                @"FWFWKWebViewConfigurationHostApi api (%@) doesn't respond to "
                @"@selector(setMediaTypesRequiresUserActionForConfigurationWithIdentifier:forTypes:"
                @"error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSArray<FWFWKAudiovisualMediaTypeEnumData *> *arg_types = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setMediaTypesRequiresUserActionForConfigurationWithIdentifier:arg_identifier
                                                                  forTypes:arg_types
                                                                     error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
NSObject<FlutterMessageCodec> *FWFWKWebViewConfigurationFlutterApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

@interface FWFWKWebViewConfigurationFlutterApi ()
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
@end

@implementation FWFWKWebViewConfigurationFlutterApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
  self = [super init];
  if (self) {
    _binaryMessenger = binaryMessenger;
  }
  return self;
}
- (void)createWithIdentifier:(NSNumber *)arg_identifier
                  completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.WKWebViewConfigurationFlutterApi.create"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKWebViewConfigurationFlutterApiGetCodec()];
  [channel sendMessage:@[ arg_identifier ?: [NSNull null] ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
@end
@interface FWFWKUserContentControllerHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKUserContentControllerHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFWKUserScriptData fromList:[self readValue]];

    case 129:
      return [FWFWKUserScriptInjectionTimeEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKUserContentControllerHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKUserContentControllerHostApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKUserContentControllerHostApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKUserContentControllerHostApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKUserContentControllerHostApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKUserContentControllerHostApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKUserContentControllerHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKUserContentControllerHostApiCodecReaderWriter *readerWriter =
        [[FWFWKUserContentControllerHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

void FWFWKUserContentControllerHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                            NSObject<FWFWKUserContentControllerHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.WKUserContentControllerHostApi.createFromWebViewConfiguration"
        binaryMessenger:binaryMessenger
                  codec:FWFWKUserContentControllerHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(createFromWebViewConfigurationWithIdentifier:
                                                                 configurationIdentifier:error:)],
          @"FWFWKUserContentControllerHostApi api (%@) doesn't respond to "
          @"@selector(createFromWebViewConfigurationWithIdentifier:configurationIdentifier:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewConfigurationWithIdentifier:arg_identifier
                                  configurationIdentifier:arg_configurationIdentifier
                                                    error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKUserContentControllerHostApi.addScriptMessageHandler"
        binaryMessenger:binaryMessenger
                  codec:FWFWKUserContentControllerHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (addScriptMessageHandlerForControllerWithIdentifier:
                                                       handlerIdentifier:ofName:error:)],
                @"FWFWKUserContentControllerHostApi api (%@) doesn't respond to "
                @"@selector(addScriptMessageHandlerForControllerWithIdentifier:handlerIdentifier:"
                @"ofName:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_handlerIdentifier = GetNullableObjectAtIndex(args, 1);
        NSString *arg_name = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api addScriptMessageHandlerForControllerWithIdentifier:arg_identifier
                                              handlerIdentifier:arg_handlerIdentifier
                                                         ofName:arg_name
                                                          error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.WKUserContentControllerHostApi.removeScriptMessageHandler"
        binaryMessenger:binaryMessenger
                  codec:FWFWKUserContentControllerHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (removeScriptMessageHandlerForControllerWithIdentifier:name:error:)],
                @"FWFWKUserContentControllerHostApi api (%@) doesn't respond to "
                @"@selector(removeScriptMessageHandlerForControllerWithIdentifier:name:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSString *arg_name = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api removeScriptMessageHandlerForControllerWithIdentifier:arg_identifier
                                                              name:arg_name
                                                             error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllScriptMessageHandlers"
        binaryMessenger:binaryMessenger
                  codec:FWFWKUserContentControllerHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (removeAllScriptMessageHandlersForControllerWithIdentifier:error:)],
                @"FWFWKUserContentControllerHostApi api (%@) doesn't respond to "
                @"@selector(removeAllScriptMessageHandlersForControllerWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api removeAllScriptMessageHandlersForControllerWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKUserContentControllerHostApi.addUserScript"
        binaryMessenger:binaryMessenger
                  codec:FWFWKUserContentControllerHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(addUserScriptForControllerWithIdentifier:
                                                                                userScript:error:)],
                @"FWFWKUserContentControllerHostApi api (%@) doesn't respond to "
                @"@selector(addUserScriptForControllerWithIdentifier:userScript:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FWFWKUserScriptData *arg_userScript = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api addUserScriptForControllerWithIdentifier:arg_identifier
                                           userScript:arg_userScript
                                                error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKUserContentControllerHostApi.removeAllUserScripts"
        binaryMessenger:binaryMessenger
                  codec:FWFWKUserContentControllerHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (removeAllUserScriptsForControllerWithIdentifier:error:)],
                @"FWFWKUserContentControllerHostApi api (%@) doesn't respond to "
                @"@selector(removeAllUserScriptsForControllerWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api removeAllUserScriptsForControllerWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
NSObject<FlutterMessageCodec> *FWFWKPreferencesHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

void FWFWKPreferencesHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                  NSObject<FWFWKPreferencesHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKPreferencesHostApi.createFromWebViewConfiguration"
        binaryMessenger:binaryMessenger
                  codec:FWFWKPreferencesHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(createFromWebViewConfigurationWithIdentifier:
                                                                 configurationIdentifier:error:)],
          @"FWFWKPreferencesHostApi api (%@) doesn't respond to "
          @"@selector(createFromWebViewConfigurationWithIdentifier:configurationIdentifier:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewConfigurationWithIdentifier:arg_identifier
                                  configurationIdentifier:arg_configurationIdentifier
                                                    error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKPreferencesHostApi.setJavaScriptEnabled"
        binaryMessenger:binaryMessenger
                  codec:FWFWKPreferencesHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (setJavaScriptEnabledForPreferencesWithIdentifier:isEnabled:error:)],
                @"FWFWKPreferencesHostApi api (%@) doesn't respond to "
                @"@selector(setJavaScriptEnabledForPreferencesWithIdentifier:isEnabled:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_enabled = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setJavaScriptEnabledForPreferencesWithIdentifier:arg_identifier
                                                    isEnabled:arg_enabled
                                                        error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
NSObject<FlutterMessageCodec> *FWFWKScriptMessageHandlerHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

void FWFWKScriptMessageHandlerHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                           NSObject<FWFWKScriptMessageHandlerHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKScriptMessageHandlerHostApi.create"
        binaryMessenger:binaryMessenger
                  codec:FWFWKScriptMessageHandlerHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createWithIdentifier:error:)],
                @"FWFWKScriptMessageHandlerHostApi api (%@) doesn't respond to "
                @"@selector(createWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FWFWKScriptMessageHandlerFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKScriptMessageHandlerFlutterApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFWKScriptMessageData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKScriptMessageHandlerFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKScriptMessageHandlerFlutterApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKScriptMessageHandlerFlutterApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKScriptMessageHandlerFlutterApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKScriptMessageHandlerFlutterApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter *readerWriter =
        [[FWFWKScriptMessageHandlerFlutterApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

@interface FWFWKScriptMessageHandlerFlutterApi ()
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
@end

@implementation FWFWKScriptMessageHandlerFlutterApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
  self = [super init];
  if (self) {
    _binaryMessenger = binaryMessenger;
  }
  return self;
}
- (void)didReceiveScriptMessageForHandlerWithIdentifier:(NSNumber *)arg_identifier
                        userContentControllerIdentifier:
                            (NSNumber *)arg_userContentControllerIdentifier
                                                message:(FWFWKScriptMessageData *)arg_message
                                             completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:
          @"dev.flutter.pigeon.WKScriptMessageHandlerFlutterApi.didReceiveScriptMessage"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKScriptMessageHandlerFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_userContentControllerIdentifier ?: [NSNull null],
    arg_message ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
@end
NSObject<FlutterMessageCodec> *FWFWKNavigationDelegateHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

void FWFWKNavigationDelegateHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                         NSObject<FWFWKNavigationDelegateHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKNavigationDelegateHostApi.create"
        binaryMessenger:binaryMessenger
                  codec:FWFWKNavigationDelegateHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createWithIdentifier:error:)],
                @"FWFWKNavigationDelegateHostApi api (%@) doesn't respond to "
                @"@selector(createWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FWFWKNavigationDelegateFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKNavigationDelegateFlutterApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFNSErrorData fromList:[self readValue]];

    case 129:
      return [FWFNSUrlRequestData fromList:[self readValue]];

    case 130:
      return [FWFWKFrameInfoData fromList:[self readValue]];

    case 131:
      return [FWFWKNavigationActionData fromList:[self readValue]];

    case 132:
      return [FWFWKNavigationActionPolicyEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKNavigationDelegateFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKNavigationDelegateFlutterApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFNSErrorData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:130];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:131];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
    [self writeByte:132];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKNavigationDelegateFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKNavigationDelegateFlutterApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKNavigationDelegateFlutterApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKNavigationDelegateFlutterApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKNavigationDelegateFlutterApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKNavigationDelegateFlutterApiCodecReaderWriter *readerWriter =
        [[FWFWKNavigationDelegateFlutterApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

@interface FWFWKNavigationDelegateFlutterApi ()
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
@end

@implementation FWFWKNavigationDelegateFlutterApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
  self = [super init];
  if (self) {
    _binaryMessenger = binaryMessenger;
  }
  return self;
}
- (void)didFinishNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
                                   webViewIdentifier:(NSNumber *)arg_webViewIdentifier
                                                 URL:(nullable NSString *)arg_url
                                          completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:
          @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
    arg_url ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
- (void)didStartProvisionalNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
                                             webViewIdentifier:(NSNumber *)arg_webViewIdentifier
                                                           URL:(nullable NSString *)arg_url
                                                    completion:
                                                        (void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:
          @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didStartProvisionalNavigation"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
    arg_url ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
- (void)
    decidePolicyForNavigationActionForDelegateWithIdentifier:(NSNumber *)arg_identifier
                                           webViewIdentifier:(NSNumber *)arg_webViewIdentifier
                                            navigationAction:
                                                (FWFWKNavigationActionData *)arg_navigationAction
                                                  completion:
                                                      (void (^)(FWFWKNavigationActionPolicyEnumData
                                                                    *_Nullable,
                                                                NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:
          @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.decidePolicyForNavigationAction"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
    arg_navigationAction ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   FWFWKNavigationActionPolicyEnumData *output = reply;
                   completion(output, nil);
                 }];
}
- (void)didFailNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
                                 webViewIdentifier:(NSNumber *)arg_webViewIdentifier
                                             error:(FWFNSErrorData *)arg_error
                                        completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailNavigation"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
    arg_error ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
- (void)didFailProvisionalNavigationForDelegateWithIdentifier:(NSNumber *)arg_identifier
                                            webViewIdentifier:(NSNumber *)arg_webViewIdentifier
                                                        error:(FWFNSErrorData *)arg_error
                                                   completion:
                                                       (void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:
          @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFailProvisionalNavigation"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
    arg_error ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
- (void)webViewWebContentProcessDidTerminateForDelegateWithIdentifier:(NSNumber *)arg_identifier
                                                    webViewIdentifier:
                                                        (NSNumber *)arg_webViewIdentifier
                                                           completion:(void (^)(NSError *_Nullable))
                                                                          completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:
          @"dev.flutter.pigeon.WKNavigationDelegateFlutterApi.webViewWebContentProcessDidTerminate"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKNavigationDelegateFlutterApiGetCodec()];
  [channel sendMessage:@[ arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null] ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
@end
@interface FWFNSObjectHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFNSObjectHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFNSKeyValueObservingOptionsEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFNSObjectHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFNSObjectHostApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFNSObjectHostApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFNSObjectHostApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFNSObjectHostApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFNSObjectHostApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFNSObjectHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFNSObjectHostApiCodecReaderWriter *readerWriter =
        [[FWFNSObjectHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

void FWFNSObjectHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                             NSObject<FWFNSObjectHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.NSObjectHostApi.dispose"
        binaryMessenger:binaryMessenger
                  codec:FWFNSObjectHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(disposeObjectWithIdentifier:error:)],
                @"FWFNSObjectHostApi api (%@) doesn't respond to "
                @"@selector(disposeObjectWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api disposeObjectWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.NSObjectHostApi.addObserver"
        binaryMessenger:binaryMessenger
                  codec:FWFNSObjectHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (addObserverForObjectWithIdentifier:
                                      observerIdentifier:keyPath:options:error:)],
                @"FWFNSObjectHostApi api (%@) doesn't respond to "
                @"@selector(addObserverForObjectWithIdentifier:observerIdentifier:keyPath:options:"
                @"error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_observerIdentifier = GetNullableObjectAtIndex(args, 1);
        NSString *arg_keyPath = GetNullableObjectAtIndex(args, 2);
        NSArray<FWFNSKeyValueObservingOptionsEnumData *> *arg_options =
            GetNullableObjectAtIndex(args, 3);
        FlutterError *error;
        [api addObserverForObjectWithIdentifier:arg_identifier
                             observerIdentifier:arg_observerIdentifier
                                        keyPath:arg_keyPath
                                        options:arg_options
                                          error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.NSObjectHostApi.removeObserver"
        binaryMessenger:binaryMessenger
                  codec:FWFNSObjectHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(removeObserverForObjectWithIdentifier:
                                                               observerIdentifier:keyPath:error:)],
          @"FWFNSObjectHostApi api (%@) doesn't respond to "
          @"@selector(removeObserverForObjectWithIdentifier:observerIdentifier:keyPath:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_observerIdentifier = GetNullableObjectAtIndex(args, 1);
        NSString *arg_keyPath = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api removeObserverForObjectWithIdentifier:arg_identifier
                                observerIdentifier:arg_observerIdentifier
                                           keyPath:arg_keyPath
                                             error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FWFNSObjectFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFNSObjectFlutterApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFNSErrorData fromList:[self readValue]];

    case 129:
      return [FWFNSHttpCookieData fromList:[self readValue]];

    case 130:
      return [FWFNSHttpCookiePropertyKeyEnumData fromList:[self readValue]];

    case 131:
      return [FWFNSKeyValueChangeKeyEnumData fromList:[self readValue]];

    case 132:
      return [FWFNSKeyValueObservingOptionsEnumData fromList:[self readValue]];

    case 133:
      return [FWFNSUrlRequestData fromList:[self readValue]];

    case 134:
      return [FWFWKAudiovisualMediaTypeEnumData fromList:[self readValue]];

    case 135:
      return [FWFWKFrameInfoData fromList:[self readValue]];

    case 136:
      return [FWFWKNavigationActionData fromList:[self readValue]];

    case 137:
      return [FWFWKNavigationActionPolicyEnumData fromList:[self readValue]];

    case 138:
      return [FWFWKScriptMessageData fromList:[self readValue]];

    case 139:
      return [FWFWKUserScriptData fromList:[self readValue]];

    case 140:
      return [FWFWKUserScriptInjectionTimeEnumData fromList:[self readValue]];

    case 141:
      return [FWFWKWebsiteDataTypeEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFNSObjectFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFNSObjectFlutterApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFNSErrorData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
    [self writeByte:130];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) {
    [self writeByte:131];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
    [self writeByte:132];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:133];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
    [self writeByte:134];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:135];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:136];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
    [self writeByte:137];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
    [self writeByte:138];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
    [self writeByte:139];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
    [self writeByte:140];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
    [self writeByte:141];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFNSObjectFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFNSObjectFlutterApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFNSObjectFlutterApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFNSObjectFlutterApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFNSObjectFlutterApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFNSObjectFlutterApiCodecReaderWriter *readerWriter =
        [[FWFNSObjectFlutterApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

@interface FWFNSObjectFlutterApi ()
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
@end

@implementation FWFNSObjectFlutterApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
  self = [super init];
  if (self) {
    _binaryMessenger = binaryMessenger;
  }
  return self;
}
- (void)observeValueForObjectWithIdentifier:(NSNumber *)arg_identifier
                                    keyPath:(NSString *)arg_keyPath
                           objectIdentifier:(NSNumber *)arg_objectIdentifier
                                 changeKeys:
                                     (NSArray<FWFNSKeyValueChangeKeyEnumData *> *)arg_changeKeys
                               changeValues:(NSArray<id> *)arg_changeValues
                                 completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.NSObjectFlutterApi.observeValue"
             binaryMessenger:self.binaryMessenger
                       codec:FWFNSObjectFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_keyPath ?: [NSNull null],
    arg_objectIdentifier ?: [NSNull null], arg_changeKeys ?: [NSNull null],
    arg_changeValues ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
- (void)disposeObjectWithIdentifier:(NSNumber *)arg_identifier
                         completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.NSObjectFlutterApi.dispose"
             binaryMessenger:self.binaryMessenger
                       codec:FWFNSObjectFlutterApiGetCodec()];
  [channel sendMessage:@[ arg_identifier ?: [NSNull null] ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
@end
@interface FWFWKWebViewHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKWebViewHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFNSErrorData fromList:[self readValue]];

    case 129:
      return [FWFNSHttpCookieData fromList:[self readValue]];

    case 130:
      return [FWFNSHttpCookiePropertyKeyEnumData fromList:[self readValue]];

    case 131:
      return [FWFNSKeyValueChangeKeyEnumData fromList:[self readValue]];

    case 132:
      return [FWFNSKeyValueObservingOptionsEnumData fromList:[self readValue]];

    case 133:
      return [FWFNSUrlRequestData fromList:[self readValue]];

    case 134:
      return [FWFWKAudiovisualMediaTypeEnumData fromList:[self readValue]];

    case 135:
      return [FWFWKFrameInfoData fromList:[self readValue]];

    case 136:
      return [FWFWKNavigationActionData fromList:[self readValue]];

    case 137:
      return [FWFWKNavigationActionPolicyEnumData fromList:[self readValue]];

    case 138:
      return [FWFWKScriptMessageData fromList:[self readValue]];

    case 139:
      return [FWFWKUserScriptData fromList:[self readValue]];

    case 140:
      return [FWFWKUserScriptInjectionTimeEnumData fromList:[self readValue]];

    case 141:
      return [FWFWKWebsiteDataTypeEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKWebViewHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKWebViewHostApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFNSErrorData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
    [self writeByte:130];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) {
    [self writeByte:131];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
    [self writeByte:132];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:133];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
    [self writeByte:134];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:135];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:136];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
    [self writeByte:137];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
    [self writeByte:138];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
    [self writeByte:139];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
    [self writeByte:140];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
    [self writeByte:141];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKWebViewHostApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKWebViewHostApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKWebViewHostApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKWebViewHostApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKWebViewHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKWebViewHostApiCodecReaderWriter *readerWriter =
        [[FWFWKWebViewHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

void FWFWKWebViewHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                              NSObject<FWFWKWebViewHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.create"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createWithIdentifier:
                                               configurationIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(createWithIdentifier:configurationIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createWithIdentifier:arg_identifier
            configurationIdentifier:arg_configurationIdentifier
                              error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.setUIDelegate"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(setUIDelegateForWebViewWithIdentifier:
                                                                     delegateIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(setUIDelegateForWebViewWithIdentifier:delegateIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_uiDelegateIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setUIDelegateForWebViewWithIdentifier:arg_identifier
                                delegateIdentifier:arg_uiDelegateIdentifier
                                             error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.setNavigationDelegate"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(setNavigationDelegateForWebViewWithIdentifier:
                                                                       delegateIdentifier:error:)],
          @"FWFWKWebViewHostApi api (%@) doesn't respond to "
          @"@selector(setNavigationDelegateForWebViewWithIdentifier:delegateIdentifier:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_navigationDelegateIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setNavigationDelegateForWebViewWithIdentifier:arg_identifier
                                        delegateIdentifier:arg_navigationDelegateIdentifier
                                                     error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.getUrl"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(URLForWebViewWithIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(URLForWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSString *output = [api URLForWebViewWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.getEstimatedProgress"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(estimatedProgressForWebViewWithIdentifier:
                                                                                      error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(estimatedProgressForWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api estimatedProgressForWebViewWithIdentifier:arg_identifier
                                                                    error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.loadRequest"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(loadRequestForWebViewWithIdentifier:
                                                                              request:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(loadRequestForWebViewWithIdentifier:request:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FWFNSUrlRequestData *arg_request = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api loadRequestForWebViewWithIdentifier:arg_identifier request:arg_request error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.loadHtmlString"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(loadHTMLForWebViewWithIdentifier:
                                                                        HTMLString:baseURL:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(loadHTMLForWebViewWithIdentifier:HTMLString:baseURL:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSString *arg_string = GetNullableObjectAtIndex(args, 1);
        NSString *arg_baseUrl = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api loadHTMLForWebViewWithIdentifier:arg_identifier
                                   HTMLString:arg_string
                                      baseURL:arg_baseUrl
                                        error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.loadFileUrl"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (loadFileForWebViewWithIdentifier:fileURL:readAccessURL:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(loadFileForWebViewWithIdentifier:fileURL:readAccessURL:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSString *arg_url = GetNullableObjectAtIndex(args, 1);
        NSString *arg_readAccessUrl = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api loadFileForWebViewWithIdentifier:arg_identifier
                                      fileURL:arg_url
                                readAccessURL:arg_readAccessUrl
                                        error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.loadFlutterAsset"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(loadAssetForWebViewWithIdentifier:
                                                                           assetKey:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(loadAssetForWebViewWithIdentifier:assetKey:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSString *arg_key = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api loadAssetForWebViewWithIdentifier:arg_identifier assetKey:arg_key error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.canGoBack"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(canGoBackForWebViewWithIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(canGoBackForWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api canGoBackForWebViewWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.canGoForward"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(canGoForwardForWebViewWithIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(canGoForwardForWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api canGoForwardForWebViewWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.goBack"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(goBackForWebViewWithIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(goBackForWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api goBackForWebViewWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.goForward"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(goForwardForWebViewWithIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(goForwardForWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api goForwardForWebViewWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.reload"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(reloadWebViewWithIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(reloadWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api reloadWebViewWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.getTitle"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(titleForWebViewWithIdentifier:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(titleForWebViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSString *output = [api titleForWebViewWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.WKWebViewHostApi.setAllowsBackForwardNavigationGestures"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (setAllowsBackForwardForWebViewWithIdentifier:isAllowed:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(setAllowsBackForwardForWebViewWithIdentifier:isAllowed:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_allow = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setAllowsBackForwardForWebViewWithIdentifier:arg_identifier
                                                isAllowed:arg_allow
                                                    error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.setCustomUserAgent"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(setUserAgentForWebViewWithIdentifier:
                                                                             userAgent:error:)],
                @"FWFWKWebViewHostApi api (%@) doesn't respond to "
                @"@selector(setUserAgentForWebViewWithIdentifier:userAgent:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSString *arg_userAgent = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setUserAgentForWebViewWithIdentifier:arg_identifier
                                        userAgent:arg_userAgent
                                            error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKWebViewHostApi.evaluateJavaScript"
        binaryMessenger:binaryMessenger
                  codec:FWFWKWebViewHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector
               (evaluateJavaScriptForWebViewWithIdentifier:javaScriptString:completion:)],
          @"FWFWKWebViewHostApi api (%@) doesn't respond to "
          @"@selector(evaluateJavaScriptForWebViewWithIdentifier:javaScriptString:completion:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSString *arg_javaScriptString = GetNullableObjectAtIndex(args, 1);
        [api evaluateJavaScriptForWebViewWithIdentifier:arg_identifier
                                       javaScriptString:arg_javaScriptString
                                             completion:^(id _Nullable output,
                                                          FlutterError *_Nullable error) {
                                               callback(wrapResult(output, error));
                                             }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
NSObject<FlutterMessageCodec> *FWFWKUIDelegateHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

void FWFWKUIDelegateHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                 NSObject<FWFWKUIDelegateHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKUIDelegateHostApi.create"
        binaryMessenger:binaryMessenger
                  codec:FWFWKUIDelegateHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createWithIdentifier:error:)],
                @"FWFWKUIDelegateHostApi api (%@) doesn't respond to "
                @"@selector(createWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_identifier error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FWFWKUIDelegateFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKUIDelegateFlutterApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFNSUrlRequestData fromList:[self readValue]];

    case 129:
      return [FWFWKFrameInfoData fromList:[self readValue]];

    case 130:
      return [FWFWKNavigationActionData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKUIDelegateFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKUIDelegateFlutterApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:130];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKUIDelegateFlutterApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKUIDelegateFlutterApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKUIDelegateFlutterApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKUIDelegateFlutterApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKUIDelegateFlutterApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKUIDelegateFlutterApiCodecReaderWriter *readerWriter =
        [[FWFWKUIDelegateFlutterApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

@interface FWFWKUIDelegateFlutterApi ()
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
@end

@implementation FWFWKUIDelegateFlutterApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
  self = [super init];
  if (self) {
    _binaryMessenger = binaryMessenger;
  }
  return self;
}
- (void)onCreateWebViewForDelegateWithIdentifier:(NSNumber *)arg_identifier
                               webViewIdentifier:(NSNumber *)arg_webViewIdentifier
                         configurationIdentifier:(NSNumber *)arg_configurationIdentifier
                                navigationAction:(FWFWKNavigationActionData *)arg_navigationAction
                                      completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.WKUIDelegateFlutterApi.onCreateWebView"
             binaryMessenger:self.binaryMessenger
                       codec:FWFWKUIDelegateFlutterApiGetCodec()];
  [channel sendMessage:@[
    arg_identifier ?: [NSNull null], arg_webViewIdentifier ?: [NSNull null],
    arg_configurationIdentifier ?: [NSNull null], arg_navigationAction ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
@end
@interface FWFWKHttpCookieStoreHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKHttpCookieStoreHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFNSHttpCookieData fromList:[self readValue]];

    case 129:
      return [FWFNSHttpCookiePropertyKeyEnumData fromList:[self readValue]];

    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FWFWKHttpCookieStoreHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKHttpCookieStoreHostApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FWFWKHttpCookieStoreHostApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FWFWKHttpCookieStoreHostApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FWFWKHttpCookieStoreHostApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FWFWKHttpCookieStoreHostApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FWFWKHttpCookieStoreHostApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FWFWKHttpCookieStoreHostApiCodecReaderWriter *readerWriter =
        [[FWFWKHttpCookieStoreHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

void FWFWKHttpCookieStoreHostApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                      NSObject<FWFWKHttpCookieStoreHostApi> *api) {
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKHttpCookieStoreHostApi.createFromWebsiteDataStore"
        binaryMessenger:binaryMessenger
                  codec:FWFWKHttpCookieStoreHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createFromWebsiteDataStoreWithIdentifier:
                                                                       dataStoreIdentifier:error:)],
                @"FWFWKHttpCookieStoreHostApi api (%@) doesn't respond to "
                @"@selector(createFromWebsiteDataStoreWithIdentifier:dataStoreIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_websiteDataStoreIdentifier = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebsiteDataStoreWithIdentifier:arg_identifier
                                  dataStoreIdentifier:arg_websiteDataStoreIdentifier
                                                error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKHttpCookieStoreHostApi.setCookie"
        binaryMessenger:binaryMessenger
                  codec:FWFWKHttpCookieStoreHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(setCookieForStoreWithIdentifier:
                                                                           cookie:completion:)],
                @"FWFWKHttpCookieStoreHostApi api (%@) doesn't respond to "
                @"@selector(setCookieForStoreWithIdentifier:cookie:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0);
        FWFNSHttpCookieData *arg_cookie = GetNullableObjectAtIndex(args, 1);
        [api setCookieForStoreWithIdentifier:arg_identifier
                                      cookie:arg_cookie
                                  completion:^(FlutterError *_Nullable error) {
                                    callback(wrapResult(nil, error));
                                  }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
