// 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 Cocoa import FlutterMacOS let DATE: UInt8 = 128 let PAIR: UInt8 = 129 class Pair { let first: Any? let second: Any? init(first: Any?, second: Any?) { self.first = first self.second = second } } class ExtendedWriter: FlutterStandardWriter { override func writeValue(_ value: Any) { if let date = value as? Date { self.writeByte(DATE) let time = date.timeIntervalSince1970 var ms = Int64(time * 1000.0) self.writeBytes(&ms, length: UInt(MemoryLayout<Int64>.size)) } else if let pair = value as? Pair { self.writeByte(PAIR) self.writeValue(pair.first!) self.writeValue(pair.second!) } else { super.writeValue(value) } } } class ExtendedReader: FlutterStandardReader { override func readValue(ofType type: UInt8) -> Any? { if type == DATE { var ms: Int64 = 0 self.readBytes(&ms, length: UInt(MemoryLayout<Int64>.size)) let time: Double = Double(ms) / 1000.0 return NSDate(timeIntervalSince1970: time) } else if type == PAIR { return Pair(first: self.readValue(), second: self.readValue()) } else { return super.readValue(ofType: type) } } } class ExtendedReaderWriter: FlutterStandardReaderWriter { override func reader(with data: Data) -> FlutterStandardReader { return ExtendedReader(data: data) } override func writer(with data: NSMutableData) -> FlutterStandardWriter { return ExtendedWriter(data: data) } } class MainFlutterWindow: NSWindow { override func awakeFromNib() { let flutterViewController = FlutterViewController.init() let windowFrame = self.frame self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) RegisterGeneratedPlugins(registry: flutterViewController) let registrar = flutterViewController.registrar(forPlugin: "channel-integration-test") setupMessagingHandshakeOnChannel( FlutterBasicMessageChannel( name: "binary-msg", binaryMessenger: registrar.messenger, codec: FlutterBinaryCodec.sharedInstance())) setupMessagingHandshakeOnChannel( FlutterBasicMessageChannel( name: "string-msg", binaryMessenger: registrar.messenger, codec: FlutterStringCodec.sharedInstance())) setupMessagingHandshakeOnChannel( FlutterBasicMessageChannel( name: "json-msg", binaryMessenger: registrar.messenger, codec: FlutterJSONMessageCodec.sharedInstance())) setupMessagingHandshakeOnChannel( FlutterBasicMessageChannel( name: "std-msg", binaryMessenger: registrar.messenger, codec: FlutterStandardMessageCodec(readerWriter: ExtendedReaderWriter()))) setupMethodHandshakeOnChannel( FlutterMethodChannel( name: "json-method", binaryMessenger: registrar.messenger, codec: FlutterJSONMethodCodec.sharedInstance())) setupMethodHandshakeOnChannel( FlutterMethodChannel( name: "std-method", binaryMessenger: registrar.messenger, codec: FlutterStandardMethodCodec(readerWriter: ExtendedReaderWriter()))) FlutterBasicMessageChannel( name: "std-echo", binaryMessenger: registrar.messenger, codec: FlutterStandardMessageCodec.sharedInstance() ).setMessageHandler { message, reply in reply(message) } super.awakeFromNib() } func setupMessagingHandshakeOnChannel(_ channel: FlutterBasicMessageChannel) { channel.setMessageHandler { message, reply in channel.sendMessage(message) { messageReply in channel.sendMessage(messageReply) reply(message) } } } func setupMethodHandshakeOnChannel(_ channel: FlutterMethodChannel) { channel.setMethodCallHandler { call, result in if call.method == "success" { channel.invokeMethod(call.method, arguments: call.arguments) { value in channel.invokeMethod(call.method, arguments: value) result(call.arguments) } } else if call.method == "error" { channel.invokeMethod(call.method, arguments: call.arguments) { value in let error = value as! FlutterError channel.invokeMethod(call.method, arguments: error.details) result(error) } } else { channel.invokeMethod(call.method, arguments: call.arguments) { value in channel.invokeMethod(call.method, arguments: nil) result(FlutterMethodNotImplemented) } } } } }