// 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.0.3), 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 ? error.code : [NSNull null]),
      @"message" : (error.message ? error.message : [NSNull null]),
      @"details" : (error.details ? error.details : [NSNull null]),
    };
  }
  return @{
    @"result" : (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;
- (NSDictionary *)toMap;
@end
@interface FWFWKUserScriptInjectionTimeEnumData ()
+ (FWFWKUserScriptInjectionTimeEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKAudiovisualMediaTypeEnumData ()
+ (FWFWKAudiovisualMediaTypeEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKWebsiteDataTypesEnumData ()
+ (FWFWKWebsiteDataTypesEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSHttpCookiePropertyKeyEnumData ()
+ (FWFNSHttpCookiePropertyKeyEnumData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSUrlRequestData ()
+ (FWFNSUrlRequestData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFWKUserScriptData ()
+ (FWFWKUserScriptData *)fromMap:(NSDictionary *)dict;
- (NSDictionary *)toMap;
@end
@interface FWFNSHttpCookieData ()
+ (FWFNSHttpCookieData *)fromMap:(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;
}
- (NSDictionary *)toMap {
  return [NSDictionary dictionaryWithObjectsAndKeys:@(self.value), @"value", nil];
}
@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;
}
- (NSDictionary *)toMap {
  return [NSDictionary dictionaryWithObjectsAndKeys:@(self.value), @"value", nil];
}
@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;
}
- (NSDictionary *)toMap {
  return [NSDictionary dictionaryWithObjectsAndKeys:@(self.value), @"value", nil];
}
@end

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

@implementation FWFNSHttpCookieData
+ (instancetype)makeWithProperties:
    (NSDictionary<FWFNSHttpCookiePropertyKeyEnumData *, NSString *> *)properties {
  FWFNSHttpCookieData *pigeonResult = [[FWFNSHttpCookieData alloc] init];
  pigeonResult.properties = properties;
  return pigeonResult;
}
+ (FWFNSHttpCookieData *)fromMap:(NSDictionary *)dict {
  FWFNSHttpCookieData *pigeonResult = [[FWFNSHttpCookieData alloc] init];
  pigeonResult.properties = GetNullableObject(dict, @"properties");
  NSAssert(pigeonResult.properties != nil, @"");
  return pigeonResult;
}
- (NSDictionary *)toMap {
  return [NSDictionary
      dictionaryWithObjectsAndKeys:(self.properties ? self.properties : [NSNull null]),
                                   @"properties", nil];
}
@end

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

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

@interface FWFWKWebsiteDataStoreHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKWebsiteDataStoreHostApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[FWFWKWebsiteDataTypesEnumData 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(createDataStoreFromConfigurationWithIdentifier:
                                                                   configurationIdentifier:error:)],
          @"FWFWKWebsiteDataStoreHostApi api (%@) doesn't respond to "
          @"@selector(createDataStoreFromConfigurationWithIdentifier:configurationIdentifier:error:"
          @")",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createDataStoreFromConfigurationWithIdentifier:arg_instanceId
                                    configurationIdentifier:arg_configurationInstanceId
                                                      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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createDefaultDataStoreWithIdentifier:arg_instanceId 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:secondsModifiedSinceEpoch:completion:)],
                @"FWFWKWebsiteDataStoreHostApi api (%@) doesn't respond to "
                @"@selector(removeDataFromDataStoreWithIdentifier:ofTypes:"
                @"secondsModifiedSinceEpoch:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        NSArray<FWFWKWebsiteDataTypesEnumData *> *arg_dataTypes = GetNullableObjectAtIndex(args, 1);
        NSNumber *arg_secondsModifiedSinceEpoch = GetNullableObjectAtIndex(args, 2);
        [api removeDataFromDataStoreWithIdentifier:arg_instanceId
                                           ofTypes:arg_dataTypes
                         secondsModifiedSinceEpoch:arg_secondsModifiedSinceEpoch
                                        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.getContentOffset"
        binaryMessenger:binaryMessenger
                  codec:FWFUIViewHostApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(contentOffsetForViewWithIdentifier:error:)],
                @"FWFUIViewHostApi api (%@) doesn't respond to "
                @"@selector(contentOffsetForViewWithIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSArray<NSNumber *> *output = [api contentOffsetForViewWithIdentifier:arg_instanceId
                                                                        error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_value = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setBackgroundColorForViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_opaque = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setOpaqueForViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_webViewInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewWithIdentifier:arg_instanceId
                           webViewIdentifier:arg_webViewInstanceId
                                       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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSArray<NSNumber *> *output = [api contentOffsetForScrollViewWithIdentifier:arg_instanceId
                                                                              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:
                                                                                  toX:y:error:)],
                @"FWFUIScrollViewHostApi api (%@) doesn't respond to "
                @"@selector(scrollByForScrollViewWithIdentifier:toX:y:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_x = GetNullableObjectAtIndex(args, 1);
        NSNumber *arg_y = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api scrollByForScrollViewWithIdentifier:arg_instanceId toX: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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_x = GetNullableObjectAtIndex(args, 1);
        NSNumber *arg_y = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api setContentOffsetForScrollViewWithIdentifier:arg_instanceId
                                                     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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_webViewInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewWithIdentifier:arg_instanceId
                           webViewIdentifier:arg_webViewInstanceId
                                       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:isAlowed:error:)],
          @"FWFWKWebViewConfigurationHostApi api (%@) doesn't respond to "
          @"@selector(setAllowsInlineMediaPlaybackForConfigurationWithIdentifier:isAlowed:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_allow = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setAllowsInlineMediaPlaybackForConfigurationWithIdentifier:arg_instanceId
                                                               isAlowed: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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSArray<FWFWKAudiovisualMediaTypeEnumData *> *arg_types = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setMediaTypesRequiresUserActionForConfigurationWithIdentifier:arg_instanceId
                                                                  forTypes:arg_types
                                                                     error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewConfigurationWithIdentifier:arg_instanceId
                                  configurationIdentifier:arg_configurationInstanceId
                                                    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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_handlerInstanceid = GetNullableObjectAtIndex(args, 1);
        NSString *arg_name = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api addScriptMessageHandlerForControllerWithIdentifier:arg_instanceId
                                              handlerIdentifier:arg_handlerInstanceid
                                                         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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSString *arg_name = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api removeScriptMessageHandlerForControllerWithIdentifier:arg_instanceId
                                                              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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api removeAllScriptMessageHandlersForControllerWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FWFWKUserScriptData *arg_userScript = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api addUserScriptForControllerWithIdentifier:arg_instanceId
                                           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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api removeAllUserScriptsForControllerWithIdentifier:arg_instanceId 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(createFromWebViewConfiguration:
                                                         configurationIdentifier:error:)],
                @"FWFWKPreferencesHostApi api (%@) doesn't respond to "
                @"@selector(createFromWebViewConfiguration:configurationIdentifier:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebViewConfiguration:arg_instanceId
                    configurationIdentifier:arg_configurationInstanceId
                                      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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_enabled = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setJavaScriptEnabledForPreferencesWithIdentifier:arg_instanceId
                                                    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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_instanceId error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_instanceId error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation"
        binaryMessenger:binaryMessenger
                  codec:FWFWKNavigationDelegateHostApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector
               (setDidFinishNavigationForDelegateWithIdentifier:functionIdentifier:error:)],
          @"FWFWKNavigationDelegateHostApi api (%@) doesn't respond to "
          @"@selector(setDidFinishNavigationForDelegateWithIdentifier:functionIdentifier:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_functionInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setDidFinishNavigationForDelegateWithIdentifier:arg_instanceId
                                          functionIdentifier:arg_functionInstanceId
                                                       error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FWFWKNavigationDelegateFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKNavigationDelegateFlutterApiCodecReader
@end

@interface FWFWKNavigationDelegateFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKNavigationDelegateFlutterApiCodecWriter
@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_functionInstanceId
                                   webViewIdentifier:(NSNumber *)arg_webViewInstanceId
                                                 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_functionInstanceId == nil) ? [NSNull null] : arg_functionInstanceId,
    (arg_webViewInstanceId == nil) ? [NSNull null] : arg_webViewInstanceId,
    (arg_url == nil) ? [NSNull null] : arg_url
  ]
                 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api disposeObjectWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_observerInstanceId = GetNullableObjectAtIndex(args, 1);
        NSString *arg_keyPath = GetNullableObjectAtIndex(args, 2);
        NSArray<FWFNSKeyValueObservingOptionsEnumData *> *arg_options =
            GetNullableObjectAtIndex(args, 3);
        FlutterError *error;
        [api addObserverForObjectWithIdentifier:arg_instanceId
                             observerIdentifier:arg_observerInstanceId
                                        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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_observerInstanceId = GetNullableObjectAtIndex(args, 1);
        NSString *arg_keyPath = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api removeObserverForObjectWithIdentifier:arg_instanceId
                                observerIdentifier:arg_observerInstanceId
                                           keyPath:arg_keyPath
                                             error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FWFFunctionFlutterApiCodecReader : FlutterStandardReader
@end
@implementation FWFFunctionFlutterApiCodecReader
@end

@interface FWFFunctionFlutterApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFFunctionFlutterApiCodecWriter
@end

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

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

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

@implementation FWFFunctionFlutterApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
  self = [super init];
  if (self) {
    _binaryMessenger = binaryMessenger;
  }
  return self;
}
- (void)disposeFunctionWithIdentifier:(NSNumber *)arg_instanceId
                           completion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FunctionFlutterApi.dispose"
             binaryMessenger:self.binaryMessenger
                       codec:FWFFunctionFlutterApiGetCodec()];
  [channel sendMessage:@[ (arg_instanceId == nil) ? [NSNull null] : arg_instanceId ]
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
@end
@interface FWFWKWebViewHostApiCodecReader : FlutterStandardReader
@end
@implementation FWFWKWebViewHostApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [FWFNSHttpCookieData fromMap:[self readValue]];

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

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

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

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

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

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

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

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

@interface FWFWKWebViewHostApiCodecWriter : FlutterStandardWriter
@end
@implementation FWFWKWebViewHostApiCodecWriter
- (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 if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) {
    [self writeByte:130];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) {
    [self writeByte:131];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) {
    [self writeByte:132];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) {
    [self writeByte:133];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) {
    [self writeByte:134];
    [self writeValue:[value toMap]];
  } else if ([value isKindOfClass:[FWFWKWebsiteDataTypesEnumData class]]) {
    [self writeByte:135];
    [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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_configurationInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createWithIdentifier:arg_instanceId
            configurationIdentifier:arg_configurationInstanceId
                              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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_uiDelegateInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setUIDelegateForWebViewWithIdentifier:arg_instanceId
                                delegateIdentifier:arg_uiDelegateInstanceId
                                             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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_navigationDelegateInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setNavigationDelegateForWebViewWithIdentifier:arg_instanceId
                                        delegateIdentifier:arg_navigationDelegateInstanceId
                                                     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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSString *output = [api URLForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api estimatedProgressForWebViewWithIdentifier:arg_instanceId
                                                                    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_instanceId = GetNullableObjectAtIndex(args, 0);
        FWFNSUrlRequestData *arg_request = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api loadRequestForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSString *arg_string = GetNullableObjectAtIndex(args, 1);
        NSString *arg_baseUrl = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api loadHTMLForWebViewWithIdentifier:arg_instanceId
                                   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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSString *arg_url = GetNullableObjectAtIndex(args, 1);
        NSString *arg_readAccessUrl = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        [api loadFileForWebViewWithIdentifier:arg_instanceId
                                      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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSString *arg_key = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api loadAssetForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api canGoBackForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api canGoForwardForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api goBackForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api goForwardForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api reloadWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSString *output = [api titleForWebViewWithIdentifier:arg_instanceId 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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_allow = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setAllowsBackForwardForWebViewWithIdentifier:arg_instanceId
                                                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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSString *arg_userAgent = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setUserAgentForWebViewWithIdentifier:arg_instanceId
                                        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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSString *arg_javaScriptString = GetNullableObjectAtIndex(args, 1);
        [api evaluateJavaScriptForWebViewWithIdentifier:arg_instanceId
                                       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_instanceId = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        [api createWithIdentifier:arg_instanceId error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@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_instanceId = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_websiteDataStoreInstanceId = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api createFromWebsiteDataStoreWithIdentifier:arg_instanceId
                                  dataStoreIdentifier:arg_websiteDataStoreInstanceId
                                                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:error:)],
                @"FWFWKHttpCookieStoreHostApi api (%@) doesn't respond to "
                @"@selector(setCookieForStoreWithIdentifier:cookie:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_instanceId = GetNullableObjectAtIndex(args, 0);
        FWFNSHttpCookieData *arg_cookie = GetNullableObjectAtIndex(args, 1);
        FlutterError *error;
        [api setCookieForStoreWithIdentifier:arg_instanceId cookie:arg_cookie error:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
