| // Copyright 2014 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. |
| |
| #import "AppDelegate.h" |
| #import "GeneratedPluginRegistrant.h" |
| |
| @interface Pair : NSObject |
| @property(atomic, readonly, strong, nullable) NSObject* left; |
| @property(atomic, readonly, strong, nullable) NSObject* right; |
| - (instancetype)initWithLeft:(NSObject*)first right:(NSObject*)right; |
| @end |
| |
| @implementation Pair |
| - (instancetype)initWithLeft:(NSObject*)left right:(NSObject*)right { |
| self = [super init]; |
| _left = left; |
| _right = right; |
| return self; |
| } |
| @end |
| |
| const UInt8 DATE = 128; |
| const UInt8 PAIR = 129; |
| |
| @interface ExtendedWriter : FlutterStandardWriter |
| - (void)writeValue:(id)value; |
| @end |
| |
| @implementation ExtendedWriter |
| - (void)writeValue:(id)value { |
| if ([value isKindOfClass:[NSDate class]]) { |
| [self writeByte:DATE]; |
| NSDate* date = value; |
| NSTimeInterval time = date.timeIntervalSince1970; |
| SInt64 ms = (SInt64) (time * 1000.0); |
| [self writeBytes:&ms length:8]; |
| } else if ([value isKindOfClass:[Pair class]]) { |
| Pair* pair = value; |
| [self writeByte:PAIR]; |
| [self writeValue:pair.left]; |
| [self writeValue:pair.right]; |
| } else { |
| [super writeValue:value]; |
| } |
| } |
| @end |
| |
| @interface ExtendedReader : FlutterStandardReader |
| - (id)readValueOfType:(UInt8)type; |
| @end |
| |
| @implementation ExtendedReader |
| - (id)readValueOfType:(UInt8)type { |
| switch (type) { |
| case DATE: { |
| SInt64 value; |
| [self readBytes:&value length:8]; |
| NSTimeInterval time = [NSNumber numberWithLong:value].doubleValue / 1000.0; |
| return [NSDate dateWithTimeIntervalSince1970:time]; |
| } |
| case PAIR: { |
| return [[Pair alloc] initWithLeft:[self readValue] right:[self readValue]]; |
| } |
| default: return [super readValueOfType:type]; |
| } |
| } |
| @end |
| |
| @interface ExtendedReaderWriter : FlutterStandardReaderWriter |
| - (FlutterStandardWriter*)writerWithData:(NSMutableData*)data; |
| - (FlutterStandardReader*)readerWithData:(NSData*)data; |
| @end |
| |
| @implementation ExtendedReaderWriter |
| - (FlutterStandardWriter*)writerWithData:(NSMutableData*)data { |
| return [[ExtendedWriter alloc] initWithData:data]; |
| } |
| - (FlutterStandardReader*)readerWithData:(NSData*)data { |
| return [[ExtendedReader alloc] initWithData:data]; |
| } |
| @end |
| |
| @implementation AppDelegate |
| |
| - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
| [GeneratedPluginRegistrant registerWithRegistry:self]; |
| // Override point for customization after application launch. |
| FlutterViewController *flutterController = |
| (FlutterViewController *)self.window.rootViewController; |
| |
| ExtendedReaderWriter* extendedReaderWriter = [ExtendedReaderWriter new]; |
| [self setupMessagingHandshakeOnChannel: |
| [FlutterBasicMessageChannel messageChannelWithName:@"binary-msg" |
| binaryMessenger:flutterController |
| codec:[FlutterBinaryCodec sharedInstance]]]; |
| [self setupMessagingHandshakeOnChannel: |
| [FlutterBasicMessageChannel messageChannelWithName:@"string-msg" |
| binaryMessenger:flutterController |
| codec:[FlutterStringCodec sharedInstance]]]; |
| [self setupMessagingHandshakeOnChannel: |
| [FlutterBasicMessageChannel messageChannelWithName:@"json-msg" |
| binaryMessenger:flutterController |
| codec:[FlutterJSONMessageCodec sharedInstance]]]; |
| [self setupMessagingHandshakeOnChannel: |
| [FlutterBasicMessageChannel messageChannelWithName:@"std-msg" |
| binaryMessenger:flutterController |
| codec:[FlutterStandardMessageCodec codecWithReaderWriter:extendedReaderWriter]]]; |
| [self setupMethodCallSuccessHandshakeOnChannel: |
| [FlutterMethodChannel methodChannelWithName:@"json-method" |
| binaryMessenger:flutterController |
| codec:[FlutterJSONMethodCodec sharedInstance]]]; |
| [self setupMethodCallSuccessHandshakeOnChannel: |
| [FlutterMethodChannel methodChannelWithName:@"std-method" |
| binaryMessenger:flutterController |
| codec:[FlutterStandardMethodCodec codecWithReaderWriter:extendedReaderWriter]]]; |
| |
| [[FlutterBasicMessageChannel |
| messageChannelWithName:@"std-echo" |
| binaryMessenger:flutterController |
| codec:[FlutterStandardMessageCodec |
| codecWithReaderWriter:extendedReaderWriter]] |
| setMessageHandler:^(id message, FlutterReply reply) { |
| reply(message); |
| }]; |
| |
| return [super application:application |
| didFinishLaunchingWithOptions:launchOptions]; |
| } |
| |
| - (void)setupMessagingHandshakeOnChannel:(FlutterBasicMessageChannel*)channel { |
| [channel setMessageHandler:^(id message, FlutterReply reply) { |
| [channel sendMessage:message reply:^(id messageReply) { |
| [channel sendMessage:messageReply]; |
| reply(message); |
| }]; |
| }]; |
| } |
| |
| - (void)setupMethodCallSuccessHandshakeOnChannel:(FlutterMethodChannel*)channel { |
| [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { |
| if ([call.method isEqual:@"success"]) { |
| [channel invokeMethod:call.method arguments:call.arguments result:^(id value) { |
| [channel invokeMethod:call.method arguments:value]; |
| result(call.arguments); |
| }]; |
| } else if ([call.method isEqual:@"error"]) { |
| [channel invokeMethod:call.method arguments:call.arguments result:^(id value) { |
| FlutterError* error = (FlutterError*) value; |
| [channel invokeMethod:call.method arguments:error.details]; |
| result(error); |
| }]; |
| } else { |
| [channel invokeMethod:call.method arguments:call.arguments result:^(id value) { |
| NSAssert(value == FlutterMethodNotImplemented, @"Result must be not implemented"); |
| [channel invokeMethod:call.method arguments:nil]; |
| result(FlutterMethodNotImplemented); |
| }]; |
| } |
| }]; |
| } |
| @end |