CustomPresentationExample

/*
 */
import UIKit
import MotionTransitioning
// This example demonstrates how to make use of presentation controllers to build a flexible modal
// transition that supports presenting view controllers at aribtrary frames on the screen.
class CustomPresentationExampleViewController: ExampleTableViewController {
  override init(style: UITableView.Style) {
    super.init(style: style)
    transitions = []
    // Aside: we're using a simple model pattern here to define the data for the different
    // transitions up separate from their presentation. Check out the `didSelectRowAt`
    // implementation to see how we're ultimately presenting the modal view controller.
    // By default, the vertical sheet transition will behave like a full screen transition...
    transitions.append(.init(name: "Vertical sheet", transition: VerticalSheetTransition()))
    // ...but we can also customize the frame of the presented view controller by providing a frame
    // calculation block.
    let modalDialog = VerticalSheetTransition()
    modalDialog.calculateFrameOfPresentedViewInContainerView = { info in
      guard let containerView = info.containerView else {
        assertionFailure("Missing container view during frame query.")
        return .zero
      }
      // Note: this block is retained for the lifetime of the view controller, so be careful not to
      // create a memory loop by referencing self or the presented view controller directly - use
      // the provided info structure to access these values instead.
      // Center the dialog in the container view.
      let size = CGSize(width: 200, height: 200)
      return CGRect(x: (containerView.bounds.width - size.width) / 2,
                    y: (containerView.bounds.height - size.height) / 2,
                    width: size.width,
                    height: size.height)
    }
    transitions.append(.init(name: "Modal dialog", transition: modalDialog))
  }
  override func exampleInformation() -> ExampleInfo {
    return .init(title: type(of: self).catalogBreadcrumbs().last!,
                 instructions: "Tap to present a modal transition.")
  }
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}
final class VerticalSheetTransition: NSObject, Transition {
  // When provided, the transition will use a presentation controller to customize the presentation
  // of the transition.
  var calculateFrameOfPresentedViewInContainerView: TransitionFrameCalculation?
  func start(with context: TransitionContext) {
    CATransaction.begin()
    CATransaction.setCompletionBlock {
      context.transitionDidEnd()
    }
    let shift = CASpringAnimation(keyPath: "position.y")
    // These values are extracted from UIKit's default modal presentation animation.
    shift.damping = 500
    shift.stiffness = 1000
    shift.mass = 3
    shift.duration = 0.5
    // Start off-screen...
    shift.fromValue = context.containerView.bounds.height + context.foreViewController.view.layer.bounds.height / 2
    // ...and shift on-screen.
    shift.toValue = context.foreViewController.view.layer.position.y
    if context.direction == .backward {
      let swap = shift.fromValue
      shift.fromValue = shift.toValue
      shift.toValue = swap
    }
    context.foreViewController.view.layer.add(shift, forKey: shift.keyPath)
    context.foreViewController.view.layer.setValue(shift.toValue, forKeyPath: shift.keyPath!)
    CATransaction.commit()
  }
}
extension VerticalSheetTransition: TransitionWithPresentation, TransitionWithFeasibility {
  // We customize the transition going forward but fall back to UIKit for dismissal. Our
  // presentation controller will govern both of these transitions.
  func canPerformTransition(with context: TransitionContext) -> Bool {
    return context.direction == .forward
  }
  // This method is invoked when we assign the transition to the transition controller. The result
  // is assigned to the view controller's modalPresentationStyle property.
  func defaultModalPresentationStyle() -> UIModalPresentationStyle {
    if calculateFrameOfPresentedViewInContainerView != nil {
      return .custom
    }
    return .fullScreen
  }
  func presentationController(forPresented presented: UIViewController,
                              presenting: UIViewController,
                              source: UIViewController?) -> UIPresentationController? {
    if let calculateFrameOfPresentedViewInContainerView = calculateFrameOfPresentedViewInContainerView {
      return TransitionPresentationController(presentedViewController: presented,
                                              presenting: presenting,
                                              calculateFrameOfPresentedView: calculateFrameOfPresentedViewInContainerView)
    }
    return nil
  }
}
// MARK: Supplemental code
extension CustomPresentationExampleViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
  }
}
struct TransitionInfo {
  let name: String
  let transition: Transition
}
var transitions: [TransitionInfo] = []
extension CustomPresentationExampleViewController {
  override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
  }
  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return transitions.count
  }
  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = transitions[indexPath.row].name
    return cell
  }
}
extension CustomPresentationExampleViewController {
  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let modal = ModalViewController()
    modal.mdm_transitionController.transition = transitions[indexPath.row].transition
    showDetailViewController(modal, sender: self)
  }
}


NavControllerFadeExample

/*
 */
import UIKit
import MotionTransitioning
// This example demonstrates how to build a custom UINavigationController transition using the
// Motion Transitioning APIs in Swift. The essential steps have been documented below.
class NavControllerFadeExampleViewController: ExampleViewController {
    let modalViewController = ModalViewController()
    modalViewController.title = "Example view controller"
    // The transition controller is an associated object on all UIViewController instances that
    // allows you to customize the way the view controller is presented. The primary API on the
    // controller that you'll make use of is the `transition` property. Setting this property will
    // dictate how the view controller is presented. For this example we've built a custom
    // FadeTransition, so we'll make use of that now:
    modalViewController.mdm_transitionController.transition = FadeTransition(target: .foreView)
    cachedNavDelegate = navigationController?.delegate
    // In order to customize navigation controller transitions you must implement the necessary
    // delegate methods. By setting the shared transition navigation controller delegate instance
    // we're able to customize push/pop transitions using our transitionController.
    navigationController?.delegate = TransitionNavigationControllerDelegate.sharedDelegate()
    navigationController?.pushViewController(modalViewController, animated: true)
  }
  private var cachedNavDelegate: UINavigationControllerDelegate?
  override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    if parent == nil { // Popped off
      // Restore the previous delegate, if any.
      navigationController?.delegate = cachedNavDelegate
      cachedNavDelegate = nil
    }
  }
  override func viewDidLoad() {
    super.viewDidLoad()
    let label = UILabel(frame: view.bounds)
    label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    label.textColor = .white
    label.textAlignment = .center
    label.text = "Tap to start the transition"
    view.addSubview(label)
    let tap = UITapGestureRecognizer(target: self, action: #selector(didTap))
    view.addGestureRecognizer(tap)
  }
  override func exampleInformation() -> ExampleInfo {
    return .init(title: type(of: self).catalogBreadcrumbs().last!,
                 instructions: "Tap to present a modal transition.")
  }
}


MenuExample

/*
    let modalViewController = ModalViewController()
    modalViewController.mdm_transitionController.transition = MenuTransition()
    present(modalViewController, animated: true)
  }
  override func viewDidLoad() {
    super.viewDidLoad()
    let label = UILabel(frame: view.bounds)
    label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    label.textColor = .white
    label.textAlignment = .center
    label.text = "Tap to start the transition"
    view.addSubview(label)
    let tap = UITapGestureRecognizer(target: self, action: #selector(didTap))
    view.addGestureRecognizer(tap)
  }
  override func exampleInformation() -> ExampleInfo {
    return .init(title: type(of: self).catalogBreadcrumbs().last!,
                 instructions: "Tap to present a modal transition.")
  }
}
private final class MenuTransition: NSObject, TransitionWithPresentation {
  func presentationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController?) -> UIPresentationController? {
    return nil
  }
  func defaultModalPresentationStyle() -> UIModalPresentationStyle {
    return .overCurrentContext
  }

  func start(with context: TransitionContext) {
    let foreView = context.foreViewController.view!
    if(context.direction == .forward) {
      foreView.frame.origin.x = -1 * foreView.frame.width
      UIView.animate(
        withDuration: context.duration,
        animations: {
          foreView.frame.origin.x = -1 * (foreView.frame.width / 2)
        },
        completion: { _ in
          context.transitionDidEnd()
        }
      )
    } else {
      UIView.animate(
        withDuration: context.duration,
        animations: {
          foreView.frame.origin.x = -1 * foreView.frame.width
        },
        completion: { _ in
          context.transitionDidEnd()
        }
      )
    }
  }
}


SlideUpTransition

/*
 */
import UIKit
import MotionTransitioning
// Animates the target view from off the bottom of the screen to its initial position.
final class SlideUpTransition: NSObject, Transition {
  let target: TransitionTarget
  init(target: TransitionTarget) {
    self.target = target
    super.init()
  }
  func start(with context: TransitionContext) {
    CATransaction.begin()
    CATransaction.setCompletionBlock {
      context.transitionDidEnd()
    }
    let shift = CASpringAnimation(keyPath: "position.y")
    // These values are extracted from UIKit's default modal presentation animation.
    shift.damping = 500
    shift.stiffness = 1000
    shift.mass = 3
    shift.duration = 0.5
    let snapshotter = TransitionViewSnapshotter(containerView: context.containerView)
    context.defer {
      snapshotter.removeAllSnapshots()
    }
    let snapshotTarget = snapshotter.snapshot(of: target.resolve(with: context),
                                              isAppearing: context.direction == .forward)
    // Start off-screen...
    shift.fromValue = context.containerView.bounds.height + snapshotTarget.layer.bounds.height / 2
    // ...and shift on-screen.
    shift.toValue = snapshotTarget.layer.position.y
    if context.direction == .backward {
      let swap = shift.fromValue
      shift.fromValue = shift.toValue
      shift.toValue = swap
    }
    snapshotTarget.layer.add(shift, forKey: shift.keyPath)
    snapshotTarget.layer.setValue(shift.toValue, forKeyPath: shift.keyPath!)
    CATransaction.commit()
  }
}


TransitionTarget

/*
 */
import UIKit
import MotionTransitioning
// A potential target for a transition's motion.
enum TransitionTarget {
  case backView
  case foreView
  case target(UIView)
  func resolve(with context: TransitionContext) -> UIView {
    switch self {
    case .backView:
      return context.backViewController.view
    case .foreView:
      return context.foreViewController.view
    case .target(let view):
      return view
    }
  }
}


FadeTransition

/*
 */
import UIKit
import MotionTransitioning
// Transitions must be NSObject types that conform to the Transition protocol.
final class FadeTransition: NSObject, Transition {
  enum Style {
    case fadeIn
    case fadeOut
  }
  let target: TransitionTarget
  let style: Style
  init(target: TransitionTarget, style: Style = .fadeIn) {
    self.target = target
    self.style = style
    super.init()
  }
  convenience override init() {
    self.init(target: .foreView)
  }
  // The sole method we're expected to implement, start is invoked each time the view controller is
  // presented or dismissed.
  func start(with context: TransitionContext) {
    CATransaction.begin()
    CATransaction.setCompletionBlock {
      // Let UIKit know that the transition has come to an end.
      context.transitionDidEnd()
    }
    let fade = CABasicAnimation(keyPath: "opacity")
    fade.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    switch style {
    case .fadeIn:
      fade.fromValue = 0
      fade.toValue = 1
    case .fadeOut:
      fade.fromValue = 1
      fade.toValue = 0
    }
    if context.direction == .backward {
      let swap = fade.fromValue
      fade.fromValue = fade.toValue
      fade.toValue = swap
    }
    let targetView = target.resolve(with: context)
    // Add the animation...
    targetView.layer.add(fade, forKey: fade.keyPath)
    // ...and ensure that our model layer reflects the final value.
    targetView.layer.setValue(fade.toValue, forKeyPath: fade.keyPath!)
    CATransaction.commit()
  }
}


SpringFrameTransition

/*
 */
import UIKit
import MotionTransitioning
// A small helper function for creating bi-directional animations.
// See https://github.com/material-motion/motion-animator-objc for a more versatile
// bidirectional Core Animation implementation.
func addAnimationToLayer(animation: CABasicAnimation, layer: CALayer, direction: TransitionDirection) {
  if direction == .backward {
    let swap = animation.fromValue
    animation.fromValue = animation.toValue
    animation.toValue = swap
  }
  layer.add(animation, forKey: animation.keyPath)
  layer.setValue(animation.toValue, forKeyPath: animation.keyPath!)
}
final class SpringFrameTransition: NSObject, Transition {
  let target: TransitionTarget
  let size: CGSize
  init(target: TransitionTarget, size: CGSize) {
    self.target = target
    self.size = size
    super.init()
  }
  func start(with context: TransitionContext) {
    let contextView = target.resolve(with: context)
    CATransaction.begin()
    CATransaction.setCompletionBlock {
      context.transitionDidEnd()
    }
    let shift = CASpringAnimation(keyPath: "position")
    shift.damping = 500
    shift.stiffness = 1000
    shift.mass = 3
    shift.duration = 0.5
    shift.fromValue = contextView.layer.position
    shift.toValue = CGPoint(x: context.foreViewController.view.bounds.midX,
                            y: context.foreViewController.view.bounds.midY)
    addAnimationToLayer(animation: shift, layer: contextView.layer, direction: context.direction)
    let expansion = CASpringAnimation(keyPath: "bounds.size")
    expansion.damping = 500
    expansion.stiffness = 1000
    expansion.mass = 3
    expansion.duration = 0.5
    expansion.fromValue = contextView.layer.bounds.size
    expansion.toValue = size
    addAnimationToLayer(animation: expansion, layer: contextView.layer, direction: context.direction)
    CATransaction.commit()
  }
}


CompositeTransition

/*
 */
import UIKit
import MotionTransitioning
final class CompositeTransition: NSObject, Transition, TransitionWithCustomDuration {
  let transitions: [Transition]
  init(transitions: [Transition]) {
    self.transitions = transitions
    super.init()
  }
  // The sole method we're expected to implement, start is invoked each time the view controller is
  // presented or dismissed.
  func start(with context: TransitionContext) {
    transitions.forEach { context.compose(with: $0) }
    context.transitionDidEnd()
  }
  // MARK: TransitionWithCustomDuration
  func transitionDuration(with context: TransitionContext) -> TimeInterval {
    let duration = transitions.compactMap { $0 as? TransitionWithCustomDuration }.map { $0.transitionDuration(with: context) }.max { $0 < $1 }
    if let duration = duration {
      return duration
    }
    return 0.35
  }
}


TableOfContents

/*
}
extension FadeExampleViewController {
}


AppDelegate

/*
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    let window = UIWindow(frame: UIScreen.main.bounds)
    self.window = window
    window.rootViewController = UINavigationController(rootViewController: UIViewController())
    window.makeKeyAndVisible()
    return true
  }
}


/*
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    let window = UIWindow(frame: UIScreen.main.bounds)
    self.window = window
    let rootViewController = CBCNodeListViewController(node: CBCCreateNavigationTree())
    rootViewController.title = "Transitioning"
    window.rootViewController = UINavigationController(rootViewController: rootViewController)
    window.makeKeyAndVisible()
    return true
  }
}


HexColor

/*
 */
import Foundation
import UIKit
extension UIColor {
  private convenience init(red: Int, green: Int, blue: Int) {
    assert(red >= 0 && red <= 255, "Invalid red component")
    assert(green >= 0 && green <= 255, "Invalid green component")
    assert(blue >= 0 && blue <= 255, "Invalid blue component")
    self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
  }
  convenience init(hexColor: Int) {
    self.init(red: (hexColor >> 16) & 0xff, green: (hexColor >> 8) & 0xff, blue: hexColor & 0xff)
  }
  static var primaryColor: UIColor {
    return UIColor(hexColor: 0xFF80AB)
  }
  static var secondaryColor: UIColor {
    return UIColor(hexColor: 0xC51162)
  }
  static var backgroundColor: UIColor {
    return UIColor(hexColor: 0x212121)
  }
}


ModalViewController

/*
 */
import Foundation
import UIKit
class ModalViewController: ExampleViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .primaryColor
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTap)))
    let label = UILabel(frame: view.bounds)
    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In aliquam dolor eget orci condimentum, eu blandit metus dictum. Suspendisse vitae metus pellentesque, sagittis massa vel, sodales velit. Aliquam placerat nibh et posuere interdum. Etiam fermentum purus vel turpis lobortis auctor. Curabitur auctor maximus purus, ac iaculis mi. In ac hendrerit sapien, eget porttitor risus. Integer placerat cursus viverra. Proin mollis nulla vitae nisi posuere, eu rutrum mauris condimentum. Nullam in faucibus nulla, non tincidunt lectus. Maecenas mollis massa purus, in viverra elit molestie eu. Nunc volutpat magna eget mi vestibulum pharetra. Suspendisse nulla ligula, laoreet non ante quis, vehicula facilisis libero. Morbi faucibus, sapien a convallis sodales, leo quam scelerisque leo, ut tincidunt diam velit laoreet nulla. Proin at quam vel nibh varius ultrices porta id diam. Pellentesque pretium consequat neque volutpat tristique. Sed placerat a purus ut molestie. Nullam laoreet venenatis urna non pulvinar. Proin a vestibulum nulla, eu placerat est. Morbi molestie aliquam justo, ut aliquet neque tristique consectetur. In hac habitasse platea dictumst. Fusce vehicula justo in euismod elementum. Ut vel malesuada est. Aliquam mattis, ex vel viverra eleifend, mauris nibh faucibus nibh, in fringilla sem purus vitae elit. Donec sed dapibus orci, ut vulputate sapien. Integer eu magna efficitur est pellentesque tempor. Sed ac imperdiet ex. Maecenas congue quis lacus vel dictum. Phasellus dictum mi at sollicitudin euismod. Mauris laoreet, eros vitae euismod commodo, libero ligula pretium massa, in scelerisque eros dui eu metus. Fusce elementum mauris velit, eu tempor nulla congue ut. In at tellus id quam feugiat semper eget ut felis. Nulla quis varius quam. Nullam tincidunt laoreet risus, ut aliquet nisl gravida id. Nulla iaculis mauris velit, vitae feugiat nunc scelerisque ac. Vivamus eget ligula porta, pulvinar ex vitae, sollicitudin erat. Maecenas semper ornare suscipit. Ut et neque condimentum lectus pulvinar maximus in sit amet odio. Aliquam congue purus erat, eu rutrum risus placerat a."
    label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.addSubview(label)
  }
  override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
  }
    dismiss(animated: true)
  }
}


Photo

/*
 */
import Foundation
import UIKit
struct Photo {
  let name: String
  let image: UIImage
  let uuid: String
  init(name: String) {
    self.uuid = NSUUID().uuidString
    self.name = name
    // NOTE: In a real app you should never load images from disk on the UI thread like this.
    // Instead, you should find some way to cache the thumbnails in memory and then asynchronously
    // load the full-size photos from disk/network when needed. The photo library APIs provide
    // exactly this sort of behavior (square thumbnails are accessible immediately on the UI thread
    // while the full-sized photos need to be loaded asynchronously).
    self.image = UIImage(named: "\(self.name).jpg")!
  }
}


Layout

/*
 */
import UIKit
func center(_ view: UIView, within containerView: UIView) -> UIView {
  let x = (containerView.bounds.width - view.bounds.width) / 2
  let y = (containerView.bounds.height - view.bounds.height) / 2
  view.frame = .init(origin: .init(x: x, y: y), size: view.bounds.size)
  view.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin, .flexibleLeftMargin]
  return view
}


ExampleViews

/*
 */
import UIKit
func createExampleView() -> UIView {
  let view = UIView(frame: .init(x: 0, y: 0, width: 128, height: 128))
  view.backgroundColor = .primaryColor
  view.layer.cornerRadius = view.bounds.width / 2
  return view
}
func createExampleSquareView() -> UIView {
  let view = UIView(frame: .init(x: 0, y: 0, width: 128, height: 128))
  view.backgroundColor = .primaryColor
  return view
}


ExampleViewController

/*
 */
import UIKit
struct ExampleInfo {
  let title: String
  let instructions: String
}
class ExampleViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .backgroundColor
  }
  func exampleInformation() -> ExampleInfo {
    return ExampleInfo(title: "Uninitialized", instructions: "")
  }
  override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    self.title = exampleInformation().title
  }
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}
class ExampleTableViewController: UITableViewController {
  func exampleInformation() -> ExampleInfo {
    return ExampleInfo(title: "Uninitialized", instructions: "")
  }
  convenience init() {
    self.init(style: .plain)
  }
  override init(style: UITableView.Style) {
    super.init(style: style)
    self.title = exampleInformation().title
  }
  override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    self.title = exampleInformation().title
  }
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}


PhotoAlbum

/*
 */
import Foundation
import UIKit
let numberOfImageAssets = 10
let numberOfPhotosInAlbum = 30
class PhotoAlbum {
  let photos: [Photo]
  let identifierToIndex: [String: Int]
  init() {
    var photos: [Photo] = []
    var identifierToIndex: [String: Int] = [:]
    for index in 0..<numberOfPhotosInAlbum {
      let photo = Photo(name: "image\(index % numberOfImageAssets)")
      photos.append(photo)
      identifierToIndex[photo.uuid] = index
    }
    self.photos = photos
    self.identifierToIndex = identifierToIndex
  }
}


TransitionTests

/*
 */
import XCTest
import MotionTransitioning
class TransitionTests: XCTestCase {
  private var window: UIWindow!
  override func setUp() {
    window = UIWindow()
    window.rootViewController = UIViewController()
    window.makeKeyAndVisible()
  }
  override func tearDown() {
    window = nil
  }
  func testTransitionDidEndDoesComplete() {
    let presentedViewController = UIViewController()
    presentedViewController.mdm_transitionController.transition = InstantCompletionTransition()
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.1)
    XCTAssertEqual(window.rootViewController!.presentedViewController, presentedViewController)
  }
  func testTransitionCompositionDoesComplete() {
    let presentedViewController = UIViewController()
    presentedViewController.mdm_transitionController.transition = CompositeTransition(transitions: [
      InstantCompletionTransition(),
      InstantCompletionTransition()
    ])
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.1)
    XCTAssertEqual(window.rootViewController!.presentedViewController, presentedViewController)
  }
  func testTransitionFallbackToOtherTransitionDoesComplete() {
    let presentedViewController = UIViewController()
    let transition = FallbackTransition(to: InstantCompletionTransition())
    presentedViewController.mdm_transitionController.transition = transition
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.1)
    XCTAssertFalse(transition.startWasInvoked)
    XCTAssertEqual(window.rootViewController!.presentedViewController, presentedViewController)
  }
  func testTransitionFallbackToSelfDoesComplete() {
    let presentedViewController = UIViewController()
    let transition = FallbackTransition()
    presentedViewController.mdm_transitionController.transition = transition
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.1)
    XCTAssertTrue(transition.startWasInvoked)
    XCTAssertEqual(window.rootViewController!.presentedViewController, presentedViewController)
  }
}


TransitionWithCustomDurationTests

/*
 */
import XCTest
import MotionTransitioning
final class DurationMemoryTransition: NSObject, Transition {
  var recordedDuration: TimeInterval?
  func start(with context: TransitionContext) {
    recordedDuration = context.duration
    context.transitionDidEnd()
  }
}
final class CustomDurationMemoryTransition: NSObject, TransitionWithCustomDuration {
  let duration: TimeInterval
  init(with duration: TimeInterval) {
    self.duration = duration
  }
  func transitionDuration(with context: TransitionContext) -> TimeInterval {
    return duration
  }
  var recordedDuration: TimeInterval?
  func start(with context: TransitionContext) {
    recordedDuration = context.duration
    context.transitionDidEnd()
  }
}
class TransitionWithCustomDurationTests: XCTestCase {
  private var window: UIWindow!
  override func setUp() {
    window = UIWindow()
    window.rootViewController = UIViewController()
    window.makeKeyAndVisible()
  }
  override func tearDown() {
    window = nil
  }
  func testDefaultDurationIsProvidedViaContext() {
    let presentedViewController = UIViewController()
    let transition = DurationMemoryTransition()
    presentedViewController.mdm_transitionController.transition = transition
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.1)
    // TODO: This should be an extern const in the library.
    XCTAssertEqual(transition.recordedDuration, 0.35)
    XCTAssertEqual(window.rootViewController!.presentedViewController, presentedViewController)
  }
  func testCustomDurationIsProvidedViaContext() {
    let presentedViewController = UIViewController()
    let customDuration: TimeInterval = 0.1
    let transition = CustomDurationMemoryTransition(with: customDuration)
    presentedViewController.mdm_transitionController.transition = transition
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.1)
    XCTAssertEqual(transition.recordedDuration, customDuration)
    XCTAssertEqual(window.rootViewController!.presentedViewController, presentedViewController)
  }
}


TransitionWithPresentationTests

/*
 */
import XCTest
import MotionTransitioning
class TransitionWithPresentationTests: XCTestCase {
  private var window: UIWindow!
  override func setUp() {
    window = UIWindow()
    window.rootViewController = UIViewController()
    window.makeKeyAndVisible()
  }
  override func tearDown() {
    window = nil
  }
  func testPresentationControllerIsQueriedAndCompletesWithoutAnimation() {
    let presentedViewController = UIViewController()
    presentedViewController.mdm_transitionController.transition =
      PresentationTransition(presentationControllerType: TestingPresentationController.self)
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.5)
    XCTAssert(presentedViewController.presentationController is TestingPresentationController)
  }
  func testPresentationControllerIsQueriedAndCompletesWithAnimation() {
    let presentedViewController = UIViewController()
    presentedViewController.mdm_transitionController.transition =
      PresentationTransition(presentationControllerType: TransitionPresentationController.self)
    let didComplete = expectation(description: "Did complete")
    window.rootViewController!.present(presentedViewController, animated: true) {
      didComplete.fulfill()
    }
    waitForExpectations(timeout: 0.5)
    XCTAssert(presentedViewController.presentationController is TransitionPresentationController)
  }
}
final class TestingPresentationController: UIPresentationController {
}
final class PresentationTransition: NSObject, TransitionWithPresentation {
  let presentationControllerType: UIPresentationController.Type
  init(presentationControllerType: UIPresentationController.Type) {
    self.presentationControllerType = presentationControllerType
    super.init()
  }
  func defaultModalPresentationStyle() -> UIModalPresentationStyle {
    return .custom
  }
  func presentationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController?) -> UIPresentationController? {
    return presentationControllerType.init(presentedViewController: presented, presenting: presenting)
  }
  func start(with context: TransitionContext) {
    context.transitionDidEnd()
  }
}


FallbackTransition

/*
 */
import MotionTransitioning
final class FallbackTransition: NSObject, Transition, TransitionWithFallback {
  let fallbackTo: Transition?
  init(to: Transition) {
    self.fallbackTo = to
  }
  override init() {
    self.fallbackTo = nil
  }
  func fallbackTransition(with context: TransitionContext) -> Transition {
    if let fallbackTo = fallbackTo {
      return fallbackTo
    }
    return self
  }
  var startWasInvoked = false
  func start(with context: TransitionContext) {
    startWasInvoked = true
    context.transitionDidEnd()
  }
}


InstantCompletionTransition

/*
 */
import MotionTransitioning
final class InstantCompletionTransition: NSObject, Transition {
  func start(with context: TransitionContext) {
    context.transitionDidEnd()
  }
}


CompositeTransition

/*
 */
import UIKit
import MotionTransitioning
final class CompositeTransition: NSObject, Transition, TransitionWithCustomDuration {
  let transitions: [Transition]
  init(transitions: [Transition]) {
    self.transitions = transitions
    super.init()
  }
  // The sole method we're expected to implement, start is invoked each time the view controller is
  // presented or dismissed.
  func start(with context: TransitionContext) {
    transitions.forEach { context.compose(with: $0) }
    context.transitionDidEnd()
  }
  // MARK: TransitionWithCustomDuration
  func transitionDuration(with context: TransitionContext) -> TimeInterval {
    let duration = transitions.flatMap { $0 as? TransitionWithCustomDuration }.map { $0.transitionDuration(with: context) }.max { $0 < $1 }
    if let duration = duration {
      return duration
    }
    return 0.35
  }
}


test

//
//  test.swift
//  from https://github.com/fullstackio/FlappySwift
//
//  Created by Nate Murray on 6/2/14.
//
import UIKit
import SpriteKit
extension SKNode {
    class func unarchiveFromFile(file : NSString) -> SKNode? {

        let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks")

        var sceneData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
        var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

        archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
        let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene
        archiver.finishDecoding()
        return scene
    }
}
class GameViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
            // Configure the view.
            let skView = self.view as SKView
            skView.showsFPS = true
            skView.showsNodeCount = true

            /* Sprite Kit applies additional optimizations to improve rendering performance */
            skView.ignoresSiblingOrder = true

            /* Set the scale mode to scale to fit the window */
            scene.scaleMode = .AspectFill

            skView.presentScene(scene)
        }
    }
    override func shouldAutorotate() -> Bool {
        return true
    }
    override func supportedInterfaceOrientations() -> Int {
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
            return Int(UIInterfaceOrientationMask.AllButUpsideDown.toRaw())
        } else {
            return Int(UIInterfaceOrientationMask.All.toRaw())
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

}


TFLBertTokenizerTest

class TFLBertTokenizerTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertTokenizerTest.self)
  static let mobileBertVocabPath = bundle.path(forResource: "mobilebert_vocab", ofType: "txt")!
  func testInitBertTokenizerFromPath() {
    let bertTokenizer = TFLBertTokenizer(vocabPath: TFLBertTokenizerTest.mobileBertVocabPath)
    XCTAssertNotNil(bertTokenizer)
    let tokens = bertTokenizer.tokens(fromInput: "i'm questionansweraskask")
    XCTAssertEqual(tokens, ["i", "'", "m", "question", "##ans", "##wer", "##ask", "##ask"])
    let ids = bertTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [1045, 1005, 1049, 3160, 6962, 13777, 19895, 19895])
  }
  func testInitBertTokenizerFromVocab() {
    let bertTokenizer = TFLBertTokenizer(vocab: ["hell", "##o", "wor", "##ld", "there"])
    XCTAssertNotNil(bertTokenizer)
    let tokens = bertTokenizer.tokens(fromInput: "hello there hello world")
    XCTAssertEqual(tokens, ["hell", "##o", "there", "hell", "##o", "wor", "##ld"])
    let ids = bertTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [0, 1, 4, 0, 1, 2, 3])
  }
}


TFLSentencepieceTokenizerTest

class TFLSentencepieceTokenizerTest: XCTestCase {
  static let bundle = Bundle(for: TFLSentencepieceTokenizerTest.self)
  static let spModelPath = bundle.path(forResource: "30k-clean", ofType: "model")!
  func testInitSentenpieceTokenizerFromPath() {
    let spTokenizer = TFLSentencepieceTokenizer(
      modelPath: TFLSentencepieceTokenizerTest.spModelPath)
    XCTAssertNotNil(spTokenizer)
    let tokens = spTokenizer.tokens(fromInput: "good morning, i'm your teacher.\n")
    XCTAssertEqual(tokens, ["▁good", "▁morning", ",", "▁i", "'", "m", "▁your", "▁teacher", "."])
    let ids = spTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [254, 959, 15, 31, 22, 79, 154, 2197, 9])
  }
}


TFLAudioClassifierTests

class AudioClassifierTests: XCTestCase {
  static let bundle = Bundle(for: AudioClassifierTests.self)
  static let modelPath = bundle.path(
    forResource: "yamnet_audio_classifier_with_metadata",
    ofType: "tflite")
  func verifyError(
    _ error: Error,
    expectedLocalizedDescription: String
  ) {
    XCTAssertEqual(
      error.localizedDescription,
      expectedLocalizedDescription)
  }
  func verifyCategory(
    _ category: ClassificationCategory,
    expectedIndex: NSInteger,
    expectedScore: Float,
    expectedLabel: String,
    expectedDisplayName: String?
  ) {
    XCTAssertEqual(
      category.index,
      expectedIndex)
    XCTAssertEqual(
      category.score,
      expectedScore,
      accuracy: 1e-6)
    XCTAssertEqual(
      category.label,
      expectedLabel)
    XCTAssertEqual(
      category.displayName,
      expectedDisplayName)
  }
  func verifyClassifications(
    _ classifications: Classifications,
    expectedHeadIndex: NSInteger,
    expectedCategoryCount: NSInteger
  ) {
    XCTAssertEqual(
      classifications.headIndex,
      expectedHeadIndex)
    XCTAssertEqual(
      classifications.categories.count,
      expectedCategoryCount)
  }
  func verifyClassificationResult(
    _ classificationResult: ClassificationResult,
    expectedClassificationsCount: NSInteger
  ) {
    XCTAssertEqual(
      classificationResult.classifications.count,
      expectedClassificationsCount)
  }
  func bufferFromFile(
    withName name: String,
    fileExtension: String,
    audioFormat: AudioFormat
  ) -> AVAudioPCMBuffer? {
    guard
      let filePath = AudioClassifierTests.bundle.path(
        forResource: name,
        ofType: fileExtension)
    else {
      return nil
    }
    return AVAudioPCMBuffer.loadPCMBufferFromFile(
      withPath: filePath,
      audioFormat: audioFormat)
  }
  func createAudioClassifierOptions(
    modelPath: String?
  ) throws -> AudioClassifierOptions? {
    let modelPath = try XCTUnwrap(modelPath)
    let options = AudioClassifierOptions(modelPath: modelPath)
    return options
  }
  func createAudioClassifier(
    withModelPath modelPath: String?
  ) throws -> AudioClassifier? {
    let options = try XCTUnwrap(
      self.createAudioClassifierOptions(
        modelPath: AudioClassifierTests.modelPath))
    let audioClassifier = try XCTUnwrap(
      AudioClassifier.classifier(
        options: options))
    return audioClassifier
  }
  func createAudioTensor(
    withAudioClassifier audioClassifier: AudioClassifier
  ) -> AudioTensor {
    let audioTensor = audioClassifier.createInputAudioTensor()
    return audioTensor
  }
  func loadAudioTensor(
    _ audioTensor: AudioTensor,
    fromWavFileWithName fileName: String
  ) throws {
    // Load pcm buffer from file.
    let buffer = try XCTUnwrap(
      self.bufferFromFile(
        withName: fileName,
        fileExtension: "wav",
        audioFormat: audioTensor.audioFormat))
    // Get float buffer from pcm buffer.
    let floatBuffer = try XCTUnwrap(buffer.floatBuffer)
    // Load float buffer into the audio tensor.
    try audioTensor.load(
      buffer: floatBuffer,
      offset: 0,
      size: floatBuffer.size)
  }
  func classify(
    audioTensor: AudioTensor,
    usingAudioClassifier audioClassifier: AudioClassifier
  ) throws -> ClassificationResult? {
    let classificationResult = try XCTUnwrap(
      audioClassifier.classify(
        audioTensor: audioTensor))
    let expectedClassificationsCount = 1
    self.verifyClassificationResult(
      classificationResult,
      expectedClassificationsCount: expectedClassificationsCount)
    let expectedCategoryCount = 521
    let expectedHeadIndex = 0
    self.verifyClassifications(
      classificationResult.classifications[0],
      expectedHeadIndex: expectedHeadIndex,
      expectedCategoryCount: expectedCategoryCount)
    return classificationResult
  }
  func validateForInferenceWithFloatBuffer(
    categories: [ClassificationCategory]
  ) {
    self.verifyCategory(
      categories[0],
      expectedIndex: 0,
      expectedScore: 0.957031,
      expectedLabel: "Speech",
      expectedDisplayName: nil)
    self.verifyCategory(
      categories[1],
      expectedIndex: 500,
      0.019531,               // expectedScore
      expectedLabel: "Inside, small room",
      expectedDisplayName: nil)
  }
  func testInferenceWithFloatBufferSucceeds() throws {
    let audioClassifier = try XCTUnwrap(
      self.createAudioClassifier(
        withModelPath: AudioClassifierTests.modelPath))
    let audioTensor = self.createAudioTensor(
      withAudioClassifier: audioClassifier)
    try self.loadAudioTensor(
      audioTensor, fromWavFileWithName: "speech")
    let classificationResult = try XCTUnwrap(
      self.classify(
        audioTensor: audioTensor,
        usingAudioClassifier: audioClassifier))
    self.validateForInferenceWithFloatBuffer(
      categories: classificationResult.classifications[0].categories)
  }
  func testInferenceWithNoModelPathFails() throws {
    let options = AudioClassifierOptions()
    do {
      let audioClassifier = try AudioClassifier.classifier(
        options: options)
      XCTAssertNil(audioClassifier)
    } catch {
      self.verifyError(
        error,
        expectedLocalizedDescription:
          "INVALID_ARGUMENT: Missing mandatory `model_file` field in `base_options`")
    }
  }
}


TFLImageSegmenterTests

class ImageSegmenterTests: XCTestCase {
  static let bundle = Bundle(for: ImageSegmenterTests.self)
  static let modelPath = bundle.path(
    forResource: "deeplabv3",
    ofType: "tflite")
  // The maximum fraction of pixels in the candidate mask that can have a
  // different class than the golden mask for the test to pass.
  let kGoldenMaskTolerance: Float = 1e-2
  // Magnification factor used when creating the golden category masks to make
  // them more human-friendly. Each pixel in the golden masks has its value
  // multiplied by this factor, i.e. a value of 10 means class index 1, a value of
  // 20 means class index 2, etc.
  let kGoldenMaskMagnificationFactor: UInt8 = 10
  let deepLabV3SegmentationWidth = 257
  let deepLabV3SegmentationHeight = 257
  func verifyDeeplabV3PartialSegmentationResult(_ coloredLabels: [ColoredLabel]) {
    self.verifyColoredLabel(
      coloredLabels[0],
      expectedR: 0,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "background")
    self.verifyColoredLabel(
      coloredLabels[1],
      expectedR: 128,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "aeroplane")
    self.verifyColoredLabel(
      coloredLabels[2],
      expectedR: 0,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "bicycle")
    self.verifyColoredLabel(
      coloredLabels[3],
      expectedR: 128,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "bird")
    self.verifyColoredLabel(
      coloredLabels[4],
      expectedR: 0,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "boat")
    self.verifyColoredLabel(
      coloredLabels[5],
      expectedR: 128,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "bottle")
    self.verifyColoredLabel(
      coloredLabels[6],
      expectedR: 0,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "bus")
    self.verifyColoredLabel(
      coloredLabels[7],
      expectedR: 128,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "car")
    self.verifyColoredLabel(
      coloredLabels[8],
      expectedR: 64,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "cat")
    self.verifyColoredLabel(
      coloredLabels[9],
      expectedR: 192,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "chair")
    self.verifyColoredLabel(
      coloredLabels[10],
      expectedR: 64,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "cow")
    self.verifyColoredLabel(
      coloredLabels[11],
      expectedR: 192,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "dining table")
    self.verifyColoredLabel(
      coloredLabels[12],
      expectedR: 64,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "dog")
    self.verifyColoredLabel(
      coloredLabels[13],
      expectedR: 192,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "horse")
    self.verifyColoredLabel(
      coloredLabels[14],
      expectedR: 64,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "motorbike")
    self.verifyColoredLabel(
      coloredLabels[15],
      expectedR: 192,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "person")
    self.verifyColoredLabel(
      coloredLabels[16],
      expectedR: 0,
      expectedG: 64,
      expectedB: 0,
      expectedLabel: "potted plant")
    self.verifyColoredLabel(
      coloredLabels[17],
      expectedR: 128,
      expectedG: 64,
      expectedB: 0,
      expectedLabel: "sheep")
    self.verifyColoredLabel(
      coloredLabels[18],
      expectedR: 0,
      expectedG: 192,
      expectedB: 0,
      expectedLabel: "sofa")
    self.verifyColoredLabel(
      coloredLabels[19],
      expectedR: 128,
      expectedG: 192,
      expectedB: 0,
      expectedLabel: "train")
    self.verifyColoredLabel(
      coloredLabels[20],
      expectedR: 0,
      expectedG: 64,
      expectedB: 128,
      expectedLabel: "tv")
  }
  func verifyColoredLabel(
    _ coloredLabel: ColoredLabel,
    expectedR: UInt,
    expectedG: UInt,
    expectedB: UInt,
    expectedLabel: String
  ) {
    XCTAssertEqual(
      coloredLabel.r,
      expectedR)
    XCTAssertEqual(
      coloredLabel.g,
      expectedG)
    XCTAssertEqual(
      coloredLabel.b,
      expectedB)
    XCTAssertEqual(
      coloredLabel.label,
      expectedLabel)
  }
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ImageSegmenterTests.modelPath)
    let imageSegmenterOptions = ImageSegmenterOptions(modelPath: modelPath)
    let imageSegmenter =
      try ImageSegmenter.segmenter(options: imageSegmenterOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "segmentation_input_rotation0",
        type: "jpg"))
    let segmentationResult: SegmentationResult =
      try XCTUnwrap(imageSegmenter.segment(mlImage: gmlImage))
    XCTAssertEqual(segmentationResult.segmentations.count, 1)
    let coloredLabels = try XCTUnwrap(segmentationResult.segmentations[0].coloredLabels)
    verifyDeeplabV3PartialSegmentationResult(coloredLabels)
    let categoryMask = try XCTUnwrap(segmentationResult.segmentations[0].categoryMask)
    XCTAssertEqual(deepLabV3SegmentationWidth, categoryMask.width)
    XCTAssertEqual(deepLabV3SegmentationHeight, categoryMask.height)
    let goldenMaskImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "segmentation_golden_rotation0",
        type: "png"))
    let pixelBuffer = goldenMaskImage.grayScalePixelBuffer().takeRetainedValue()
    CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.readOnly)
    let pixelBufferBaseAddress = (try XCTUnwrap(CVPixelBufferGetBaseAddress(pixelBuffer)))
      .assumingMemoryBound(to: UInt8.self)
    let numPixels = deepLabV3SegmentationWidth * deepLabV3SegmentationHeight
    let mask = try XCTUnwrap(categoryMask.mask)
    var inconsistentPixels: Float = 0.0
    for i in 0..<numPixels {
      if mask[i] * kGoldenMaskMagnificationFactor != pixelBufferBaseAddress[i] {
        inconsistentPixels += 1
      }
    }
    CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.readOnly)
    XCTAssertLessThan(inconsistentPixels / Float(numPixels), kGoldenMaskTolerance)
  }
}


TFLObjectDetectorTests

class ObjectDetectorTests: XCTestCase {
  static let bundle = Bundle(for: ObjectDetectorTests.self)
  static let modelPath = bundle.path(
    forResource: "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29",
    ofType: "tflite")
  func verifyDetectionResult(_ detectionResult: DetectionResult) {
    XCTAssertGreaterThan(detectionResult.detections.count, 0)
    self.verifyDetection(
      detectionResult.detections[0],
      expectedBoundingBox: CGRect(x: 54, y: 396, width: 393, height: 199),
      expectedFirstScore: 0.632812,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[1],
      expectedBoundingBox: CGRect(x: 602, y: 157, width: 394, height: 447),
      expectedFirstScore: 0.609375,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[2],
      expectedBoundingBox: CGRect(x: 260, y: 394, width: 179, height: 209),
      expectedFirstScore: 0.5625,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[3],
      expectedBoundingBox: CGRect(x: 387, y: 197, width: 281, height: 409),
      expectedFirstScore: 0.488281,
      expectedFirstLabel: "dog")
  }
  func verifyDetection(
    _ detection: Detection, expectedBoundingBox: CGRect,
    expectedFirstScore: Float,
    expectedFirstLabel: String
  ) {
    XCTAssertGreaterThan(detection.categories.count, 0)
    XCTAssertEqual(
      detection.boundingBox.origin.x,
      expectedBoundingBox.origin.x)
    XCTAssertEqual(
      detection.boundingBox.origin.y,
      expectedBoundingBox.origin.y)
    XCTAssertEqual(
      detection.boundingBox.size.width,
      expectedBoundingBox.size.width)
    XCTAssertEqual(
      detection.boundingBox.size.height,
      expectedBoundingBox.size.height)
    XCTAssertEqual(
      detection.categories[0].label,
      expectedFirstLabel)
    XCTAssertEqual(
      detection.categories[0].score,
      expectedFirstScore, accuracy: 0.001)
  }
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ObjectDetectorTests.modelPath)
    let objectDetectorOptions = ObjectDetectorOptions(modelPath: modelPath)
    let objectDetector =
      try ObjectDetector.detector(options: objectDetectorOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "cats_and_dogs",
        type: "jpg"))
    let detectionResults: DetectionResult =
      try objectDetector.detect(mlImage: gmlImage)
    self.verifyDetectionResult(detectionResults)
  }
  func testModelOptionsWithMaxResults() throws {
    let modelPath = try XCTUnwrap(ObjectDetectorTests.modelPath)
    let objectDetectorOptions = ObjectDetectorOptions(modelPath: modelPath)
    let maxResults = 3
    objectDetectorOptions.classificationOptions.maxResults = maxResults
    let objectDetector =
      try ObjectDetector.detector(options: objectDetectorOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "cats_and_dogs",
        type: "jpg"))
    let detectionResult: DetectionResult = try objectDetector.detect(
      mlImage: gmlImage)
    XCTAssertLessThanOrEqual(detectionResult.detections.count, maxResults)
    self.verifyDetection(
      detectionResult.detections[0],
      expectedBoundingBox: CGRect(x: 54, y: 396, width: 393, height: 199),
      expectedFirstScore: 0.632812,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[1],
      expectedBoundingBox: CGRect(x: 602, y: 157, width: 394, height: 447),
      expectedFirstScore: 0.609375,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[2],
      expectedBoundingBox: CGRect(x: 260, y: 394, width: 179, height: 209),
      expectedFirstScore: 0.5625,
      expectedFirstLabel: "cat")
  }
}


TFLImageClassifierTests

class ImageClassifierTests: XCTestCase {
  static let bundle = Bundle(for: ImageClassifierTests.self)
  static let modelPath = bundle.path(
    forResource: "mobilenet_v2_1.0_224",
    ofType: "tflite")
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "burger",
        type: "jpg"))
    let classificationResults: ClassificationResult =
      try imageClassifier.classify(mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    // TODO: match the score as image_classifier_test.cc
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "cheeseburger")
    XCTAssertEqual(category.score, 0.748976, accuracy: 0.001)
  }
  func testModelOptionsWithMaxResults() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let maxResults = 3
    imageClassifierOptions.classificationOptions.maxResults = maxResults
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "burger",
        type: "jpg"))
    let classificationResults: ClassificationResult = try imageClassifier.classify(
      mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertLessThanOrEqual(classificationResults.classifications[0].categories.count, maxResults)
    // TODO: match the score as image_classifier_test.cc
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "cheeseburger")
    XCTAssertEqual(category.score, 0.748976, accuracy: 0.001)
  }
  func testInferenceWithBoundingBox() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "multi_objects",
        type: "jpg"))
    let roi = CGRect(x: 406, y: 110, width: 148, height: 153)
    let classificationResults =
      try imageClassifier.classify(mlImage: gmlImage, regionOfInterest: roi)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    // TODO: match the label and score as image_classifier_test.cc
    // let category = classificationResults.classifications[0].categories[0]
    // XCTAssertEqual(category.label, "soccer ball")
    // XCTAssertEqual(category.score, 0.256512, accuracy:0.001);
  }
  func testInferenceWithRGBAImage() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "sparrow",
        type: "png"))
    let classificationResults =
      try imageClassifier.classify(mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "junco")
    XCTAssertEqual(category.score, 0.253016, accuracy: 0.001)
  }
}


TFLNLClassifierTest

class TFLNLClassifierTest: XCTestCase {
  static let bundle = Bundle(for: TFLNLClassifierTest.self)
  static let modelPath = bundle.path(
    forResource: "test_model_nl_classifier_with_regex_tokenizer",
    ofType: "tflite")!
  var modelOptions:TFLNLClassifierOptions!;
  override func setUp() {
    modelOptions = TFLNLClassifierOptions()
    modelOptions.inputTensorName = "input_text"
    modelOptions.outputScoreTensorName = "probability"
  }
  func testClassifyPositiveResult() {
    let nlClassifier = TFLNLClassifier.nlClassifier(
      modelPath: TFLNLClassifierTest.modelPath,
      options: modelOptions)
    XCTAssertNotNil(nlClassifier)
    let categories = nlClassifier.classify(
      text: "This is the best movie I’ve seen in recent years. Strongly recommend it!")
    XCTAssertGreaterThan(categories["Positive"]!.doubleValue, categories["Negative"]!.doubleValue)
  }
   func testClassifyNegativeResult() {
     let nlClassifier = TFLNLClassifier.nlClassifier(
       modelPath: TFLNLClassifierTest.modelPath,
       options: modelOptions)
     XCTAssertNotNil(nlClassifier)
     let categories = nlClassifier.classify(text: "What a waste of my time.")
     XCTAssertGreaterThan(categories["Negative"]!.doubleValue, categories["Positive"]!.doubleValue)
   }
}


TFLBertNLClassifierTest

class TFLBertNLClassifierTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertNLClassifierTest.self)
  static let bertModelPath = bundle.path(forResource: "bert_nl_classifier", ofType: "tflite")!
  func testClassifyPositiveResult() {
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "it's a charming and often affecting journey")
    XCTAssertGreaterThan(categories["positive"]!.doubleValue, categories["negative"]!.doubleValue)
  }
  func testClassifyNegativeResult() {
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "unflinchingly bleak and desperate")
    XCTAssertGreaterThan(categories["negative"]!.doubleValue, categories["positive"]!.doubleValue)
  }
  func testCreateFromOptionsClassifyPositiveResult() {
    let modelOptions = TFLBertNLClassifierOptions()
    modelOptions.maxSeqLen = 128
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath,
      options: modelOptions)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "it's a charming and often affecting journey")
    XCTAssertGreaterThan(categories["positive"]!.doubleValue, categories["negative"]!.doubleValue)
  }
  func testCreateFromOptionsClassifyNegativeResult() {
    let modelOptions = TFLBertNLClassifierOptions()
    modelOptions.maxSeqLen = 128
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath,
      options: modelOptions)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "unflinchingly bleak and desperate")
    XCTAssertGreaterThan(categories["negative"]!.doubleValue, categories["positive"]!.doubleValue)
  }
}


TFLBertQuestionAnswererTest

class TFLBertQuestionAnswererTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertQuestionAnswererTest.self)
  static let mobileBertModelPath = bundle.path(forResource: "mobilebert_with_metadata", ofType: "tflite")!
  static let albertModelPath = bundle.path(forResource: "albert_with_metadata", ofType: "tflite")!
  static let context = """
    The role of teacher is often formal and ongoing, carried out at a school or other place of
    formal education. In many countries, a person who wishes to become a teacher must first obtain
     specified professional qualifications or credentials from a university or college. These
    professional qualifications may include the study of pedagogy, the science of teaching.
    Teachers, like other professionals, may have to continue their education after they qualify,
    a process known as continuing professional development. Teachers may use a lesson plan to
    facilitate student learning, providing a course of study which is called the curriculum.
    """
  static let question = "What is a course of study called?"
  static let answer = "the curriculum."
  func testInitMobileBert() {
    let mobileBertAnswerer = TFLBertQuestionAnswerer.questionAnswerer(
      modelPath: TFLBertQuestionAnswererTest.mobileBertModelPath)
    XCTAssertNotNil(mobileBertAnswerer)
    let answers = mobileBertAnswerer.answer(
      context: TFLBertQuestionAnswererTest.context, question: TFLBertQuestionAnswererTest.question)
    XCTAssertNotNil(answers)
    XCTAssertEqual(answers[0].text, TFLBertQuestionAnswererTest.answer)
  }
  func testInitAlbert() {
    let albertAnswerer = TFLBertQuestionAnswerer.questionAnswerer(
      modelPath: TFLBertQuestionAnswererTest.albertModelPath)
    XCTAssertNotNil(albertAnswerer)
    let answers = albertAnswerer.answer(
      context: TFLBertQuestionAnswererTest.context, question: TFLBertQuestionAnswererTest.question)
    XCTAssertNotNil(answers)
    XCTAssertEqual(answers[0].text, TFLBertQuestionAnswererTest.answer)
  }
}


AppDelegate

import UIKit
import Flutter
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}


GeneratedPluginRegistrant

//
//  Generated file. Do not edit.
//

import FlutterMacOS
import Foundation

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
}


AppDelegate

import Cocoa
import FlutterMacOS
class AppDelegate: FlutterAppDelegate {
  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    return true
  }
}


MainFlutterWindow

import Cocoa
import FlutterMacOS

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)

    super.awakeFromNib()
  }
}


CodableVariable

import Foundation
///   }
///   ```
///
/// The same issue also applies to other auto-synthesized Codable types, including classes, structs
/// and enums (Swift 5.5+). This is because Optional<Int> is a pure Swift type that cannot be
/// represented in Objective-C land. As a workaround, developers can declare a new method in the
/// class extension as below:
///
///   ```
///   extension FooClass {
public class CodableVariable: NSObject, NSSecureCoding, Codable {
  /// Error thrown by `CodableVariable` during the decoding.
  public enum DecodingError: Error, LocalizedError {
    /// The type of encoded data doesn't match the caller's expecting type.
    /// - expectedType: The type expected by the decoding method caller.
    /// - actualType: The type of the encoded data.
    case typeUnmatched(expectedType: String, actualType: String)
    public var errorDescription: String? {
      switch self {
      case let .typeUnmatched(expectedType, actualType):
        return "Expecting to decode \(expectedType) but the codable variable is \(actualType)."
      }
    }
  }
  internal static let typeKey = "EDOTypeKey"
  internal let data: Data
  internal let type: String
  /// Creates `CodableVariable` instance with a `Codable` instance.
  ///
  /// - Parameter parameter: The Codable instance to be wrapped.
  /// - Returns: A `CodableVariable` instance.
  /// - Throws: Errors propagated from JSONEncoder when encoding `parameter`.
  public static func wrap<T: Encodable>(_ parameter: T) throws -> CodableVariable {
    let encoder = JSONEncoder()
    return CodableVariable(data: try encoder.encode(parameter), type: String(describing: T.self))
  }
  internal init(data: Data, type: String) {
    self.data = data
    self.type = type
  }
  /// Decodes the Codable instance.
  ///
  /// - Parameter type: The expected type of the decoded instance.
  /// - Returns: The decoded instance of `type`.
  /// - Throws: `CodableVariable.DecodingError` if decoding fails.
  public func unwrap<T: Decodable>() throws -> T {
    guard self.type == String(describing: T.self) else {
      throw DecodingError.typeUnmatched(
        expectedType: self.type,
        actualType: String(describing: T.self))
    }
    let decoder = JSONDecoder()
    return try decoder.decode(T.self, from: data)
  }
  // MARK - NSSecureCoding
  public required init?(coder: NSCoder) {
    guard let data = coder.decodeData(),
      let type = coder.decodeObject(forKey: CodableVariable.typeKey) as? String
    else {
      return nil
    }
    self.data = data
    self.type = type
  }
  public func encode(with coder: NSCoder) {
    coder.encode(data)
    coder.encode(type, forKey: CodableVariable.typeKey)
  }
}
/// Extends Encodable to easily produce `CodableVariable` from the instance.
extension Encodable {
  /// Produces a `CodableVariable` instance from `self`.
  public var eDOCodableVariable: CodableVariable {
    // try! is used here because`CodableVariable.wrap` only throws programmer errors when
    // JSONEncoder fails to encode a `Encodable` type.
    return try! CodableVariable.wrap(self)
  }
}


Dummy

//
//
// Dummy empty swift file to enable Xcode swift compilation.
import Foundation


CodableVariableTests

import XCTest
import SwiftUtil

struct EDOTestingStruct: Codable {
  var intValue: Int
  var stringValue: String
  var floatValue: Float
}

final class CodableVariableTests: XCTestCase {

  /// Verifies CodableVariable can wrap/unwrap structs that conforms Codable.
  func testSerializeStruct() throws {
    let structValue = EDOTestingStruct(intValue: 0, stringValue: "foo", floatValue: -1.0)
    let serialized = structValue.eDOCodableVariable
    let deserialized: EDOTestingStruct = try serialized.unwrap()
    XCTAssertEqual(deserialized.intValue, structValue.intValue)
    XCTAssertEqual(deserialized.stringValue, structValue.stringValue)
    XCTAssertEqual(deserialized.floatValue, structValue.floatValue)
  }

  /// Verifies CodableVariable can wrap/unwrap optional primitive types.
  func testSerializeOptionalPrimitive() throws {
    guard #available(iOS 13.0, *) else {
      throw XCTSkip("Optional is available for encoding after iOS 13")
    }
    let optionalValue: Int? = nil
    let serialized = optionalValue.eDOCodableVariable
    let deserialized: Int? = try serialized.unwrap()
    XCTAssertNil(deserialized)
  }

  /// Verifies CodableVariable throws exceptions when decoding expects a wrong type.
  func testThrowErrorWhenTypeMismatch() {
    let structValue = EDOTestingStruct(intValue: 0, stringValue: "foo", floatValue: -1.0)
    let serialized = structValue.eDOCodableVariable
    var thrownError: Error?
    XCTAssertThrowsError(try serialized.unwrap() as Int?) {
      thrownError = $0
    }
    let expectedError =
      CodableVariable.DecodingError.typeUnmatched(
        expectedType: "EDOTestingStruct",
        actualType: "Optional<Int>")
    XCTAssertEqual(thrownError?.localizedDescription, expectedError.localizedDescription)
  }

}


EDOSwiftUITest

//
  func launchAppWithPort(port: Int, value: Int) -> XCUIApplication {
    let application = XCUIApplication()
    application.launchArguments = [
      "-servicePort", String(format: "%d", port), String("-dummyInitValue"),
      String(format: "%d", value),
    ]
    application.launch()
    return application
  }
  func testRemoteInvocation() {
    launchAppWithPort(port: 1234, value: 10)
    let service = EDOHostService(port: 2234, rootObject: self, queue: DispatchQueue.main)
    let hostPort = EDOHostPort(port: 1234, name: nil, deviceSerialNumber: nil)
    let testDummy = EDOClientService<EDOTestDummyExtension>.rootObject(with: hostPort)
    let swiftClass = testDummy.returnProtocol()
    XCTAssertEqual(swiftClass.returnString(), "Swift String")
    XCTAssertEqual(
      swiftClass.returnWithBlock { (str: NSString) in
        XCTAssertEqual(str, "Block")
        return swiftClass
      }, "Swift StringBlock")
    service.invalidate()
  }
  func testRemoteInvocationWithParameter() throws {
    launchAppWithPort(port: 1234, value: 10)
    let service = EDOHostService(port: 2234, rootObject: self, queue: DispatchQueue.main)
    let hostPort = EDOHostPort(port: 1234, name: nil, deviceSerialNumber: nil)
    let testDummy = EDOClientService<EDOTestDummyExtension>.rootObject(with: hostPort)
    let swiftClass = testDummy.returnProtocol()
    let data = ["a": 1, "b": 2] as NSDictionary
    XCTAssertEqual(swiftClass.returnWithDictionarySum(data: data.passByValue()), 3)
    XCTAssertEqual(swiftClass.returnWithDictionarySum(data: data), 3)
    let testingStruct = EDOTestSwiftStruct(intValues: [1, 2, 3, 4, 5])
    let codedResult = try swiftClass.sumFrom(codedStruct: testingStruct.eDOCodableVariable)
    let result: [Int] = try codedResult.unwrap()
    XCTAssertEqual(result.first, 15)
    service.invalidate()
  }
  /// Verifies Swift array can be passed across the process and used by other Swift code.
  func testRemoteSwiftArray() {
    launchAppWithPort(port: 1234, value: 10)
    let service = EDOHostService(port: 2234, rootObject: self, queue: DispatchQueue.main)
    let hostPort = EDOHostPort(port: 1234, name: nil, deviceSerialNumber: nil)
    let testDummy = EDOClientService<EDOTestDummyExtension>.rootObject(with: hostPort)
    let swiftClass = testDummy.returnProtocol()
    let target = swiftClass.returnSwiftArray()
    XCTAssertNotNil(target[0])
    XCTAssertNotNil(target[1])
    service.invalidate()
  }
  /// Verifies Swift error is propagated through `throw`, and can be accessed through `localizedDescription`.
  func testRemoteSwiftError() {
    launchAppWithPort(port: 1234, value: 10)
    let service = EDOHostService(port: 2234, rootObject: self, queue: DispatchQueue.main)
    let hostPort = EDOHostPort(port: 1234, name: nil, deviceSerialNumber: nil)
    let testDummy = EDOClientService<EDOTestDummyExtension>.rootObject(with: hostPort)
      .returnProtocol()
    var propagatedError: AnyObject? = nil
    do {
      try testDummy.propagateError(withCustomizedDescription: false)
    } catch EDOTestError.intentionalError {
      XCTFail("Remote Swift error is identified locally, which is supported before")
    } catch {
      propagatedError = error as AnyObject
    }
    XCTAssertTrue(propagatedError?.localizedDescription?.contains("EDOTestError") ?? false)
    do {
      try testDummy.propagateError(withCustomizedDescription: true)
    } catch EDOCustomizedTestError.intentionalError {
      XCTFail("Remote Swift error is identified locally, which is supported before")
    } catch {
      propagatedError = error as AnyObject
    }
    XCTAssertEqual(
      propagatedError?.localizedDescription,
      "An override for EDOCustomizedTestError.intentionalError")
    service.invalidate()
  }
}


EDOTestSwiftClass

//
    return block("Block").returnString().appending("Block") as NSString
  }
  public func returnWithDictionarySum(data: NSDictionary) -> Int {
    var sum = 0
    for key in data.allKeys {
      sum += (data.object(forKey: key) as! NSNumber).intValue
    }
    return sum
  }
  public func returnSwiftArray() -> [AnyObject] {
    return [NSObject.init(), NSObject.init()]
  }
  public func sumFrom(structValue: EDOTestSwiftStruct) -> [Int] {
    return [structValue.intValues.reduce(0) { $0 + $1 }]
  }
  public func sumFrom(codedStruct: CodableVariable) throws -> CodableVariable {
    let structValue: EDOTestSwiftStruct = try codedStruct.unwrap()
    return self.sumFrom(structValue: structValue).eDOCodableVariable
  }
  public func propagateError(withCustomizedDescription isCustomized: Bool) throws {
    if isCustomized {
      throw EDOCustomizedTestError.intentionalError
    } else {
      throw EDOTestError.intentionalError
    }
  }
}
extension EDOTestDummy: EDOTestDummyExtension {
  open func returnProtocol() -> EDOTestSwiftProtocol {
    return EDOTestSwiftClass()
  }
}


EDOTestSwiftProtocol

//
//
import Foundation
import SwiftUtil
public struct EDOTestSwiftStruct: Codable {
  public var intValues: [Int]
  public init(intValues: [Int]) {
    self.intValues = intValues
  }
}
public enum EDOTestError: Swift.Error {
  case intentionalError
}
public enum EDOCustomizedTestError: Swift.Error {
  case intentionalError
}
extension EDOCustomizedTestError: LocalizedError {
  public var errorDescription: String? {
    switch self {
    case .intentionalError:
      return NSLocalizedString(
        "An override for EDOCustomizedTestError.intentionalError", comment: "EDOCustomizedTestError"
      )
    }
  }
}
public protocol EDOTestDummyExtension {
  func returnProtocol() -> EDOTestSwiftProtocol
}


GPBSwiftTests

// Protocol Buffers - Google's data interchange format
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
import Foundation
import XCTest
// Test some usage of the ObjC library from Swift.
class GPBBridgeTests: XCTestCase {
  func testProto2Basics() {
    let msg = Message2()
    let msg2 = Message2()
    let msg3 = Message2_OptionalGroup()
    msg.optionalInt32 = 100
    msg.optionalString = "abc"
    msg.optionalEnum = .bar
    msg2.optionalString = "other"
    msg.optional = msg2
    msg3.a = 200
    msg.optionalGroup = msg3
    msg.repeatedInt32Array.addValue(300)
    msg.repeatedInt32Array.addValue(301)
    msg.repeatedStringArray.add("mno")
    msg.repeatedStringArray.add("pqr")
    msg.repeatedEnumArray.addValue(Message2_Enum.bar.rawValue)
    msg.repeatedEnumArray.addValue(Message2_Enum.baz.rawValue)
    msg.mapInt32Int32.setInt32(400, forKey:500)
    msg.mapInt32Int32.setInt32(401, forKey:501)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600)
    msg.mapInt32Enum.setEnum(Message2_Enum.baz.rawValue, forKey:601)
    // Check has*.
    XCTAssertTrue(msg.hasOptionalInt32)
    XCTAssertTrue(msg.hasOptionalString)
    XCTAssertTrue(msg.hasOptionalEnum)
    XCTAssertTrue(msg2.hasOptionalString)
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg3.hasA)
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertFalse(msg.hasOptionalInt64)
    XCTAssertFalse(msg.hasOptionalFloat)
    // Check values.
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalString, "abc")
    XCTAssertEqual(msg2.optionalString, "other")
    XCTAssertTrue(msg.optional === msg2)
    XCTAssertEqual(msg.optionalEnum, Message2_Enum.bar)
    XCTAssertEqual(msg3.a, Int32(200))
    XCTAssertTrue(msg.optionalGroup === msg3)
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(2))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 0), Int32(300))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 1), Int32(301))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.repeatedStringArray.object(at: 0) as? String, "mno")
    XCTAssertEqual(msg.repeatedStringArray.object(at: 1) as? String, "pqr")
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(2))
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 0), Message2_Enum.bar.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 1), Message2_Enum.baz.rawValue)
    XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    var intValue: Int32 = 0
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 500))
    XCTAssertEqual(intValue, Int32(400))
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 501))
    XCTAssertEqual(intValue, Int32(401))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo")
    XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc")
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
    XCTAssertEqual(intValue, Message2_Enum.bar.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
    XCTAssertEqual(intValue, Message2_Enum.baz.rawValue)
    // Clearing a string with nil.
    msg2.optionalString = nil
    XCTAssertFalse(msg2.hasOptionalString)
    XCTAssertEqual(msg2.optionalString, "")
    // Clearing a message with nil.
    msg.optionalGroup = nil
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optionalGroup !== msg3)  // New instance
    // Clear.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalInt32)
    XCTAssertFalse(msg.hasOptionalString)
    XCTAssertFalse(msg.hasOptionalEnum)
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalInt64)
    XCTAssertFalse(msg.hasOptionalFloat)
    XCTAssertEqual(msg.optionalInt32, Int32(0))
    XCTAssertEqual(msg.optionalString, "")
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    XCTAssertEqual(msg.optionalEnum, Message2_Enum.foo)  // Default
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(0))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
    XCTAssertEqual(msg.mapStringString.count, Int(0))
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
  }
  func testProto3Basics() {
    let msg = Message3()
    let msg2 = Message3()
    msg.optionalInt32 = 100
    msg.optionalString = "abc"
    msg.optionalEnum = .bar
    msg2.optionalString = "other"
    msg.optional = msg2
    msg.repeatedInt32Array.addValue(300)
    msg.repeatedInt32Array.addValue(301)
    msg.repeatedStringArray.add("mno")
    msg.repeatedStringArray.add("pqr")
    // "proto3" syntax lets enum get unknown values.
    msg.repeatedEnumArray.addValue(Message3_Enum.bar.rawValue)
    msg.repeatedEnumArray.addRawValue(666)
    SetMessage3_OptionalEnum_RawValue(msg2, 666)
    msg.mapInt32Int32.setInt32(400, forKey:500)
    msg.mapInt32Int32.setInt32(401, forKey:501)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600)
    // "proto3" syntax lets enum get unknown values.
    msg.mapInt32Enum.setRawValue(666, forKey:601)
    // Has only exists on for message fields.
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertFalse(msg2.hasOptionalMessage)
    // Check values.
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalString, "abc")
    XCTAssertEqual(msg2.optionalString, "other")
    XCTAssertTrue(msg.optional === msg2)
    XCTAssertEqual(msg.optionalEnum, Message3_Enum.bar)
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(2))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 0), Int32(300))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 1), Int32(301))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.repeatedStringArray.object(at: 0) as? String, "mno")
    XCTAssertEqual(msg.repeatedStringArray.object(at: 1) as? String, "pqr")
    XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(2))
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 0), Message3_Enum.bar.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 1), Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.rawValue(at: 1), 666)
    XCTAssertEqual(msg2.optionalEnum, Message3_Enum.gpbUnrecognizedEnumeratorValue)
    XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Int32(666))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    var intValue: Int32 = 0
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:500))
    XCTAssertEqual(intValue, Int32(400))
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:501))
    XCTAssertEqual(intValue, Int32(401))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo")
    XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc")
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
    XCTAssertEqual(intValue, Message2_Enum.bar.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
    XCTAssertEqual(intValue, Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getRawValue(&intValue, forKey:601))
    XCTAssertEqual(intValue, 666)
    // Clearing a string with nil.
    msg2.optionalString = nil
    XCTAssertEqual(msg2.optionalString, "")
    // Clearing a message with nil.
    msg.optional = nil
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    // Clear.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertEqual(msg.optionalInt32, Int32(0))
    XCTAssertEqual(msg.optionalString, "")
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    XCTAssertEqual(msg.optionalEnum, Message3_Enum.foo)  // Default
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(0))
    msg2.clear()
    XCTAssertEqual(msg2.optionalEnum, Message3_Enum.foo)  // Default
    XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Message3_Enum.foo.rawValue)
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
    XCTAssertEqual(msg.mapStringString.count, Int(0))
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
  }
  func testAutoCreation() {
    let msg = Message2()
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.hasOptionalMessage)
    // Access shouldn't result in has* but should return objects.
    let msg2 = msg.optionalGroup
    let msg3 = msg.optional.optional
    let msg4 = msg.optional
    XCTAssertNotNil(msg2)
    XCTAssertNotNil(msg3)
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.optional.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalMessage)
    // Setting things should trigger has* getting set.
    msg.optionalGroup.a = 10
    msg.optional.optional.optionalInt32 = 100
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optional.hasOptionalMessage)
    XCTAssertTrue(msg.hasOptionalMessage)
    // And they should be the same pointer as before.
    XCTAssertTrue(msg2 === msg.optionalGroup)
    XCTAssertTrue(msg3 === msg.optional.optional)
    XCTAssertTrue(msg4 === msg.optional)
    // Clear gets us new objects next time around.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.optional.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalMessage)
    msg.optionalGroup.a = 20
    msg.optional.optional.optionalInt32 = 200
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optional.hasOptionalMessage)
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg2 !== msg.optionalGroup)
    XCTAssertTrue(msg3 !== msg.optional.optional)
    XCTAssertTrue(msg4 !== msg.optional)
    // Explicit set of a message, means autocreated object doesn't bind.
    msg.clear()
    let autoCreated = msg.optional
    XCTAssertFalse(msg.hasOptionalMessage)
    let msg5 = Message2()
    msg5.optionalInt32 = 123
    msg.optional = msg5
    XCTAssertTrue(msg.hasOptionalMessage)
    // Modifying the autocreated doesn't replaced the explicit set one.
    autoCreated?.optionalInt32 = 456
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg.optional === msg5)
    XCTAssertEqual(msg.optional.optionalInt32, Int32(123))
  }
  func testProto2OneOfSupport() {
    let msg = Message2()
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    let autoCreated = msg.oneof  // Default create one.
    XCTAssertNotNil(autoCreated)
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofInt32)
    msg.oneofFloat = 20.0
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(20.0))
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofFloat)
    msg.oneofEnum = .bar
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.bar)
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofEnum)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 200
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(200))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofMessage)
    // Clear the oneof.
    Message2_ClearOOneOfCase(msg)
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    let autoCreated2 = msg.oneof  // Default create one
    XCTAssertNotNil(autoCreated2)
    XCTAssertTrue(autoCreated2 !== autoCreated)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofInt32)
    // Confirm Message.clear() handles the oneof correctly.
    msg.clear()
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 300
    XCTAssertTrue(msg.oneof !== autoCreated)  // New instance
    XCTAssertTrue(msg.oneof !== autoCreated2)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(300))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofMessage)
    // Set message to nil clears the oneof.
    msg.oneof = nil
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
  }
  func testProto3OneOfSupport() {
    let msg = Message3()
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    let autoCreated = msg.oneof  // Default create one.
    XCTAssertNotNil(autoCreated)
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofInt32)
    msg.oneofFloat = 20.0
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(20.0))
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofFloat)
    msg.oneofEnum = .bar
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.bar)
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofEnum)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 200
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(200))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofMessage)
    // Clear the oneof.
    Message3_ClearOOneOfCase(msg)
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    let autoCreated2 = msg.oneof  // Default create one
    XCTAssertNotNil(autoCreated2)
    XCTAssertTrue(autoCreated2 !== autoCreated)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofInt32)
    // Confirm Message.clear() handles the oneof correctly.
    msg.clear()
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 300
    XCTAssertTrue(msg.oneof !== autoCreated)  // New instance
    XCTAssertTrue(msg.oneof !== autoCreated2)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(300))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofMessage)
    // Set message to nil clears the oneof.
    msg.oneof = nil
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
  }
  func testSerialization() {
    let msg = Message2()
    msg.optionalInt32 = 100
    msg.optionalInt64 = 101
    msg.optionalGroup.a = 102
    msg.repeatedStringArray.add("abc")
    msg.repeatedStringArray.add("def")
    msg.mapInt32Int32.setInt32(200, forKey:300)
    msg.mapInt32Int32.setInt32(201, forKey:201)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    let data = msg.data()
    let msg2 = try! Message2(data: data!)
    XCTAssertTrue(msg2 !== msg)  // New instance
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalInt64, Int64(101))
    XCTAssertEqual(msg.optionalGroup.a, Int32(102))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg2, msg)
  }
}


Package

// swift-tools-version:5.2
/*
 */
import PackageDescription
let package = Package(
  name: "FlatBuffers",
  platforms: [
    .iOS(.v11),
    .macOS(.v10_14),
  ],
  products: [
    .library(
      name: "FlatBuffers",
      targets: ["FlatBuffers"]),
  ],
  targets: [
    .target(
      name: "FlatBuffers",
      dependencies: [],
      path: "swift/Sources",
      exclude: ["Documentation.docc/Resources/code/swift"]),
  ])


// swift-tools-version:5.5
/*
 */
import PackageDescription
let package = Package(
  name: "FlatBuffers",
  platforms: [
    .iOS(.v11),
    .macOS(.v10_14),
  ],
  products: [
    .library(
      name: "FlatBuffers",
      targets: ["FlatBuffers"]),
  ],
  targets: [
    .target(
      name: "FlatBuffers",
      dependencies: [],
      path: "swift/Sources"),
  ])


// swift-tools-version:5.1
/*
 */
import PackageDescription
let package = Package(
  name: "Greeter",
  platforms: [
    .iOS(.v11),
    .macOS(.v10_14),
  ],
  dependencies: [
    .package(path: "../../../../swift"),
    .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"),
  ],
  targets: [
    // Targets are the basic building blocks of a package. A target can define a module or a test suite.
    // Targets can depend on other targets in this package, and on products in packages which this package depends on.
    .target(
      name: "Model",
      dependencies: [
        "GRPC",
        "FlatBuffers",
      ],
      path: "Sources/Model"),
    // Client for the Greeter example
    .target(
      name: "Client",
      dependencies: [
        "GRPC",
        "Model",
      ],
      path: "Sources/client"),
    // Server for the Greeter example
    .target(
      name: "Server",
      dependencies: [
        "GRPC",
        "Model",
      ],
      path: "Sources/server"),
  ])