// 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 (v3.1.5), 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 NSDictionary<NSString *, id> *wrapResult(id result, FlutterError *error) {
  NSDictionary *errorDict = (NSDictionary *)[NSNull null];
  if (error) {
    errorDict = @{
      @"code" : (error.code ?: [NSNull null]),
      @"message" : (error.message ?: [NSNull null]),
      @"details" : (error.details ?: [NSNull null]),
    };
  }
  return @{
    @"result" : (result ?: [NSNull null]),
    @"error" : errorDict,
  };
}
static id GetNullableObject(NSDictionary *dict, id key) {
  id result = dict[key];
  return (result == [NSNull null]) ? nil : result;
}
static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
  id result = array[key];
  return (result == [NSNull null]) ? nil : result;
}

@interface FWFNSKeyValueObservingOptionsEnumData ()
+ (FWFNSKeyValueObservingOptionsEnumData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFNSKeyValueObservingOptionsEnumData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSKeyValueChangeKeyEnumData ()
+ (FWFNSKeyValueChangeKeyEnumData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFNSKeyValueChangeKeyEnumData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKUserScriptInjectionTimeEnumData ()
+ (FWFWKUserScriptInjectionTimeEnumData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKUserScriptInjectionTimeEnumData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKAudiovisualMediaTypeEnumData ()
+ (FWFWKAudiovisualMediaTypeEnumData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKAudiovisualMediaTypeEnumData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKWebsiteDataTypeEnumData ()
+ (FWFWKWebsiteDataTypeEnumData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKWebsiteDataTypeEnumData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKNavigationActionPolicyEnumData ()
+ (FWFWKNavigationActionPolicyEnumData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKNavigationActionPolicyEnumData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSHttpCookiePropertyKeyEnumData ()
+ (FWFNSHttpCookiePropertyKeyEnumData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFNSHttpCookiePropertyKeyEnumData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSUrlRequestData ()
+ (FWFNSUrlRequestData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFNSUrlRequestData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKUserScriptData ()
+ (FWFWKUserScriptData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKUserScriptData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKNavigationActionData ()
+ (FWFWKNavigationActionData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKNavigationActionData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKFrameInfoData ()
+ (FWFWKFrameInfoData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKFrameInfoData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSErrorData ()
+ (FWFNSErrorData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFNSErrorData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKScriptMessageData ()
+ (FWFWKScriptMessageData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFWKScriptMessageData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSHttpCookieData ()
+ (FWFNSHttpCookieData *)fromMap:(NSDictionary *)dict;
+ (nullable FWFNSHttpCookieData *)nullableFromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end

@implementation FWFNSKeyValueObservingOptionsEnumData
+ (instancetype)makeWithValue:(FWFNSKeyValueObservingOptionsEnum)value {
  FWFNSKeyValueObservingOptionsEnumData *pigeonResult =
      [[FWFNSKeyValueObservingOptionsEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFNSKeyValueObservingOptionsEnumData *)fromMap:(NSDictionary *)dict {
  FWFNSKeyValueObservingOptionsEnumData *pigeonResult =
      [[FWFNSKeyValueObservingOptionsEnumData alloc] init];
  pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
  return pigeonResult;
}
+ (nullable FWFNSKeyValueObservingOptionsEnumData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFNSKeyValueObservingOptionsEnumData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"value" : @(self.value),
  };
}
@end

@implementation FWFNSKeyValueChangeKeyEnumData
+ (instancetype)makeWithValue:(FWFNSKeyValueChangeKeyEnum)value {
  FWFNSKeyValueChangeKeyEnumData *pigeonResult = [[FWFNSKeyValueChangeKeyEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFNSKeyValueChangeKeyEnumData *)fromMap:(NSDictionary *)dict {
  FWFNSKeyValueChangeKeyEnumData *pigeonResult = [[FWFNSKeyValueChangeKeyEnumData alloc] init];
  pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
  return pigeonResult;
}
+ (nullable FWFNSKeyValueChangeKeyEnumData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFNSKeyValueChangeKeyEnumData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"value" : @(self.value),
  };
}
@end

@implementation FWFWKUserScriptInjectionTimeEnumData
+ (instancetype)makeWithValue:(FWFWKUserScriptInjectionTimeEnum)value {
  FWFWKUserScriptInjectionTimeEnumData *pigeonResult =
      [[FWFWKUserScriptInjectionTimeEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKUserScriptInjectionTimeEnumData *)fromMap:(NSDictionary *)dict {
  FWFWKUserScriptInjectionTimeEnumData *pigeonResult =
      [[FWFWKUserScriptInjectionTimeEnumData alloc] init];
  pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
  return pigeonResult;
}
+ (nullable FWFWKUserScriptInjectionTimeEnumData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKUserScriptInjectionTimeEnumData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"value" : @(self.value),
  };
}
@end

@implementation FWFWKAudiovisualMediaTypeEnumData
+ (instancetype)makeWithValue:(FWFWKAudiovisualMediaTypeEnum)value {
  FWFWKAudiovisualMediaTypeEnumData *pigeonResult =
      [[FWFWKAudiovisualMediaTypeEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKAudiovisualMediaTypeEnumData *)fromMap:(NSDictionary *)dict {
  FWFWKAudiovisualMediaTypeEnumData *pigeonResult =
      [[FWFWKAudiovisualMediaTypeEnumData alloc] init];
  pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
  return pigeonResult;
}
+ (nullable FWFWKAudiovisualMediaTypeEnumData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKAudiovisualMediaTypeEnumData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"value" : @(self.value),
  };
}
@end

@implementation FWFWKWebsiteDataTypeEnumData
+ (instancetype)makeWithValue:(FWFWKWebsiteDataTypeEnum)value {
  FWFWKWebsiteDataTypeEnumData *pigeonResult = [[FWFWKWebsiteDataTypeEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKWebsiteDataTypeEnumData *)fromMap:(NSDictionary *)dict {
  FWFWKWebsiteDataTypeEnumData *pigeonResult = [[FWFWKWebsiteDataTypeEnumData alloc] init];
  pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
  return pigeonResult;
}
+ (nullable FWFWKWebsiteDataTypeEnumData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKWebsiteDataTypeEnumData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"value" : @(self.value),
  };
}
@end

@implementation FWFWKNavigationActionPolicyEnumData
+ (instancetype)makeWithValue:(FWFWKNavigationActionPolicyEnum)value {
  FWFWKNavigationActionPolicyEnumData *pigeonResult =
      [[FWFWKNavigationActionPolicyEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFWKNavigationActionPolicyEnumData *)fromMap:(NSDictionary *)dict {
  FWFWKNavigationActionPolicyEnumData *pigeonResult =
      [[FWFWKNavigationActionPolicyEnumData alloc] init];
  pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
  return pigeonResult;
}
+ (nullable FWFWKNavigationActionPolicyEnumData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKNavigationActionPolicyEnumData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"value" : @(self.value),
  };
}
@end

@implementation FWFNSHttpCookiePropertyKeyEnumData
+ (instancetype)makeWithValue:(FWFNSHttpCookiePropertyKeyEnum)value {
  FWFNSHttpCookiePropertyKeyEnumData *pigeonResult =
      [[FWFNSHttpCookiePropertyKeyEnumData alloc] init];
  pigeonResult.value = value;
  return pigeonResult;
}
+ (FWFNSHttpCookiePropertyKeyEnumData *)fromMap:(NSDictionary *)dict {
  FWFNSHttpCookiePropertyKeyEnumData *pigeonResult =
      [[FWFNSHttpCookiePropertyKeyEnumData alloc] init];
  pigeonResult.value = [GetNullableObject(dict, @"value") integerValue];
  return pigeonResult;
}
+ (nullable FWFNSHttpCookiePropertyKeyEnumData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFNSHttpCookiePropertyKeyEnumData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"value" : @(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 *)fromMap:(NSDictionary *)dict {
  FWFNSUrlRequestData *pigeonResult = [[FWFNSUrlRequestData alloc] init];
  pigeonResult.url = GetNullableObject(dict, @"url");
  NSAssert(pigeonResult.url != nil, @"");
  pigeonResult.httpMethod = GetNullableObject(dict, @"httpMethod");
  pigeonResult.httpBody = GetNullableObject(dict, @"httpBody");
  pigeonResult.allHttpHeaderFields = GetNullableObject(dict, @"allHttpHeaderFields");
  NSAssert(pigeonResult.allHttpHeaderFields != nil, @"");
  return pigeonResult;
}
+ (nullable FWFNSUrlRequestData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFNSUrlRequestData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"url" : (self.url ?: [NSNull null]),
    @"httpMethod" : (self.httpMethod ?: [NSNull null]),
    @"httpBody" : (self.httpBody ?: [NSNull null]),
    @"allHttpHeaderFields" : (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 *)fromMap:(NSDictionary *)dict {
  FWFWKUserScriptData *pigeonResult = [[FWFWKUserScriptData alloc] init];
  pigeonResult.source = GetNullableObject(dict, @"source");
  NSAssert(pigeonResult.source != nil, @"");
  pigeonResult.injectionTime = [FWFWKUserScriptInjectionTimeEnumData
      nullableFromMap:GetNullableObject(dict, @"injectionTime")];
  pigeonResult.isMainFrameOnly = GetNullableObject(dict, @"isMainFrameOnly");
  NSAssert(pigeonResult.isMainFrameOnly != nil, @"");
  return pigeonResult;
}
+ (nullable FWFWKUserScriptData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKUserScriptData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"source" : (self.source ?: [NSNull null]),
    @"injectionTime" : (self.injectionTime ? [self.injectionTime toMap] : [NSNull null]),
    @"isMainFrameOnly" : (self.isMainFrameOnly ?: [NSNull null]),
  };
}
@end

@implementation FWFWKNavigationActionData
+ (instancetype)makeWithRequest:(FWFNSUrlRequestData *)request
                    targetFrame:(FWFWKFrameInfoData *)targetFrame {
  FWFWKNavigationActionData *pigeonResult = [[FWFWKNavigationActionData alloc] init];
  pigeonResult.request = request;
  pigeonResult.targetFrame = targetFrame;
  return pigeonResult;
}
+ (FWFWKNavigationActionData *)fromMap:(NSDictionary *)dict {
  FWFWKNavigationActionData *pigeonResult = [[FWFWKNavigationActionData alloc] init];
  pigeonResult.request = [FWFNSUrlRequestData nullableFromMap:GetNullableObject(dict, @"request")];
  NSAssert(pigeonResult.request != nil, @"");
  pigeonResult.targetFrame =
      [FWFWKFrameInfoData nullableFromMap:GetNullableObject(dict, @"targetFrame")];
  NSAssert(pigeonResult.targetFrame != nil, @"");
  return pigeonResult;
}
+ (nullable FWFWKNavigationActionData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKNavigationActionData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"request" : (self.request ? [self.request toMap] : [NSNull null]),
    @"targetFrame" : (self.targetFrame ? [self.targetFrame toMap] : [NSNull null]),
  };
}
@end

@implementation FWFWKFrameInfoData
+ (instancetype)makeWithIsMainFrame:(NSNumber *)isMainFrame {
  FWFWKFrameInfoData *pigeonResult = [[FWFWKFrameInfoData alloc] init];
  pigeonResult.isMainFrame = isMainFrame;
  return pigeonResult;
}
+ (FWFWKFrameInfoData *)fromMap:(NSDictionary *)dict {
  FWFWKFrameInfoData *pigeonResult = [[FWFWKFrameInfoData alloc] init];
  pigeonResult.isMainFrame = GetNullableObject(dict, @"isMainFrame");
  NSAssert(pigeonResult.isMainFrame != nil, @"");
  return pigeonResult;
}
+ (nullable FWFWKFrameInfoData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKFrameInfoData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"isMainFrame" : (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 *)fromMap:(NSDictionary *)dict {
  FWFNSErrorData *pigeonResult = [[FWFNSErrorData alloc] init];
  pigeonResult.code = GetNullableObject(dict, @"code");
  NSAssert(pigeonResult.code != nil, @"");
  pigeonResult.domain = GetNullableObject(dict, @"domain");
  NSAssert(pigeonResult.domain != nil, @"");
  pigeonResult.localizedDescription = GetNullableObject(dict, @"localizedDescription");
  NSAssert(pigeonResult.localizedDescription != nil, @"");
  return pigeonResult;
}
+ (nullable FWFNSErrorData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFNSErrorData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"code" : (self.code ?: [NSNull null]),
    @"domain" : (self.domain ?: [NSNull null]),
    @"localizedDescription" : (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 *)fromMap:(NSDictionary *)dict {
  FWFWKScriptMessageData *pigeonResult = [[FWFWKScriptMessageData alloc] init];
  pigeonResult.name = GetNullableObject(dict, @"name");
  NSAssert(pigeonResult.name != nil, @"");
  pigeonResult.body = GetNullableObject(dict, @"body");
  return pigeonResult;
}
+ (nullable FWFWKScriptMessageData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFWKScriptMessageData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"name" : (self.name ?: [NSNull null]),
    @"body" : (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 *)fromMap:(NSDictionary *)dict {
  FWFNSHttpCookieData *pigeonResult = [[FWFNSHttpCookieData alloc] init];
  pigeonResult.propertyKeys = GetNullableObject(dict, @"propertyKeys");
  NSAssert(pigeonResult.propertyKeys != nil, @"");
  pigeonResult.propertyValues = GetNullableObject(dict, @"propertyValues");
  NSAssert(pigeonResult.propertyValues != nil, @"");
  return pigeonResult;
}
+ (nullable FWFNSHttpCookieData *)nullableFromMap:(NSDictionary *)dict {
  return (dict) ? [FWFNSHttpCookieData fromMap:dict] : nil;
}
- (NSDictionary *)toMap {
  return @{
    @"propertyKeys" : (self.propertyKeys ?: [NSNull null]),
    @"propertyValues" : (self.propertyValues ?: [NSNull null]),
  };
}
@end

@interface FWFWKWebsiteDataStoreHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKWebsiteDataStoreHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFWKWebsiteDataTypeEnumData fromMap:[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 toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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];
    }
  }
}
@interface FWFUIViewHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFUIViewHostApiCodecReader
@end

@interface FWFUIViewHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFUIViewHostApiCodecWriter
@end

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

NSObject<FlutterMessageCodec> *FWFUIViewHostApiGetCodec() {
  static dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  dispatch_once(&sPred, ^{
    FWFUIViewHostApiCodecReaderWriter *readerWriter =
        [[FWFUIViewHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  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];
    }
  }
}
@interface FWFUIScrollViewHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFUIScrollViewHostApiCodecReader
@end

@interface FWFUIScrollViewHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFUIScrollViewHostApiCodecWriter
@end

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

NSObject<FlutterMessageCodec> *FWFUIScrollViewHostApiGetCodec() {
  static dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  dispatch_once(&sPred, ^{
    FWFUIScrollViewHostApiCodecReaderWriter *readerWriter =
        [[FWFUIScrollViewHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  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 fromMap:[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 toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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];
    }
  }
}
@interface FWFWKWebViewConfigurationFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKWebViewConfigurationFlutterApiCodecReader
@end

@interface FWFWKWebViewConfigurationFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKWebViewConfigurationFlutterApiCodecWriter
@end

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

NSObject<FlutterMessageCodec> *FWFWKWebViewConfigurationFlutterApiGetCodec() {
  static dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  dispatch_once(&sPred, ^{
    FWFWKWebViewConfigurationFlutterApiCodecReaderWriter *readerWriter =
        [[FWFWKWebViewConfigurationFlutterApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  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 fromMap:[self readValue]];

    case 129:
      return [FWFWKUserScriptInjectionTimeEnumData fromMap:[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 toMap]];
  } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
    [self writeByte:129];
    [self writeValue:[value toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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];
    }
  }
}
@interface FWFWKPreferencesHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKPreferencesHostApiCodecReader
@end

@interface FWFWKPreferencesHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKPreferencesHostApiCodecWriter
@end

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

NSObject<FlutterMessageCodec> *FWFWKPreferencesHostApiGetCodec() {
  static dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  dispatch_once(&sPred, ^{
    FWFWKPreferencesHostApiCodecReaderWriter *readerWriter =
        [[FWFWKPreferencesHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  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];
    }
  }
}
@interface FWFWKScriptMessageHandlerHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKScriptMessageHandlerHostApiCodecReader
@end

@interface FWFWKScriptMessageHandlerHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKScriptMessageHandlerHostApiCodecWriter
@end

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

NSObject<FlutterMessageCodec> *FWFWKScriptMessageHandlerHostApiGetCodec() {
  static dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  dispatch_once(&sPred, ^{
    FWFWKScriptMessageHandlerHostApiCodecReaderWriter *readerWriter =
        [[FWFWKScriptMessageHandlerHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  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 fromMap:[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 toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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
@interface FWFWKNavigationDelegateHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKNavigationDelegateHostApiCodecReader
@end

@interface FWFWKNavigationDelegateHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKNavigationDelegateHostApiCodecWriter
@end

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

NSObject<FlutterMessageCodec> *FWFWKNavigationDelegateHostApiGetCodec() {
  static dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  dispatch_once(&sPred, ^{
    FWFWKNavigationDelegateHostApiCodecReaderWriter *readerWriter =
        [[FWFWKNavigationDelegateHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  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 fromMap:[self readValue]];

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

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

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

    case 132:
      return [FWFWKNavigationActionPolicyEnumData fromMap:[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 toMap]];
  } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:129];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:130];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:131];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
    [self writeByte:132];
    [self writeValue:[value toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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 fromMap:[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 toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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 fromMap:[self readValue]];

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

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

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

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

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

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

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

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

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

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

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

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

    case 141:
      return [FWFWKWebsiteDataTypeEnumData fromMap:[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 toMap]];
  } else if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
    [self writeByte:129];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
    [self writeByte:130];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) {
    [self writeByte:131];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
    [self writeByte:132];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:133];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
    [self writeByte:134];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:135];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:136];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
    [self writeByte:137];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
    [self writeByte:138];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
    [self writeByte:139];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
    [self writeByte:140];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
    [self writeByte:141];
    [self writeValue:[value toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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 fromMap:[self readValue]];

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

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

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

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

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

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

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

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

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

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

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

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

    case 141:
      return [FWFWKWebsiteDataTypeEnumData fromMap:[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 toMap]];
  } else if ([value isKindOfClass:[FWFNSHttpCookieData class]]) {
    [self writeByte:129];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
    [self writeByte:130];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) {
    [self writeByte:131];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
    [self writeByte:132];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:133];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
    [self writeByte:134];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:135];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:136];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) {
    [self writeByte:137];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) {
    [self writeByte:138];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
    [self writeByte:139];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
    [self writeByte:140];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) {
    [self writeByte:141];
    [self writeValue:[value toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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];
    }
  }
}
@interface FWFWKUIDelegateHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKUIDelegateHostApiCodecReader
@end

@interface FWFWKUIDelegateHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKUIDelegateHostApiCodecWriter
@end

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

NSObject<FlutterMessageCodec> *FWFWKUIDelegateHostApiGetCodec() {
  static dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  dispatch_once(&sPred, ^{
    FWFWKUIDelegateHostApiCodecReaderWriter *readerWriter =
        [[FWFWKUIDelegateHostApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  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 fromMap:[self readValue]];

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

    case 130:
      return [FWFWKNavigationActionData fromMap:[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 toMap]];
  } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) {
    [self writeByte:129];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) {
    [self writeByte:130];
    [self writeValue:[value toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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 fromMap:[self readValue]];

    case 129:
      return [FWFNSHttpCookiePropertyKeyEnumData fromMap:[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 toMap]];
  } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) {
    [self writeByte:129];
    [self writeValue:[value toMap]];
  } 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 dispatch_once_t sPred = 0;
  static FlutterStandardMessageCodec *sSharedObject = nil;
  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];
    }
  }
}
