Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell...

48
Writing a native Mac GUI application in Haskell Nikolas Mayr <[email protected]> BOBKonf2017 1

Transcript of Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell...

Page 1: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Writing a native Mac GUI application in Haskell

Nikolas Mayr <[email protected]> BOBKonf2017

1

Page 2: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Agenda• JSON Class Generator

• Joining the worlds

• Architecture

• In practice

• Retrospective

2

Page 3: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

JSON Class Generator

• Mac Application

• ~15.000 lines of Haskell

• ~ 3.000* lines of Objective-C

• Mac App Store

• Web ⬇

• Sandboxed

• lifted.software

3

Page 4: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Demo

4

Page 5: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

5

Page 6: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Recap

• Define Classes/Enums/Methods

• Export Objective-C code

• Use code to serialize/deserialize JSON

• Drop in (HTTP-)Client to connect to Service

6

Page 7: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

How Did I Write It?

• Hardcoded types in Haskell source (2014)

• Command Line Tool (2015)

• Mac/Cocoa NSDocument based GUI App (2016)

7

Page 8: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Evolution

• Hardcoded types in HS source (2014)

• Command Line Tool (2015)

• Mac/Cocoa NSDocument based GUI App (2016)

8

> api --lang objc --def api.json --out ./src/api

Page 9: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Cutting Edge

• Hardcoded types in HS source (2014)

• Command Line Tool (2015)

• Mac/Cocoa NSDocument based GUI App (2016)

9

Page 10: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Joining the Worlds

10

Page 11: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

How to Build the UI• Non-native UI

• Web

• Cross platform UI Libraries (GTK, QT)

• Native UI

• Cocoa/ObjC UI + ObjC model -> call CLT

• Cocoa/ObjC UI + HS model (together in one app)

11

Page 12: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Adding Some Glue• Communicate to HS via FFI

• c2hs

• Bindings (HoC, ObjectiveHaskell)

• language-c-inline

• Others (Apache Thrift)

• Client-Server (no network)12

Page 13: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

How Do We Connect ObjC to a Server that

Speaks JSON?

13

Page 14: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

JSON Code Generator!

14

Page 15: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

~3000 LoC + ~13000 LoC

~16000 LoC

15

ObjC Generated

⌨ ⚙

Page 16: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

How to Compile• Compiled languages

• Xcode, not Terminal

• Build phases

• HS to static library "-staticlib" => liba.a (ext. build tool)

• Generate API from specification file

• Compile ObjC (+Storyboards), copy asses/frameworks

• Link with liba.a libiconv

16

Page 17: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Compile Attempts

17

Page 18: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Application Launch

• Two runtimes to start

• Bound threads

• FFI

• -threaded

18

Page 19: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Architecture

19

Page 20: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

20

Page 21: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

21

Page 22: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

22

Page 23: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Client-Server (HS)• Stores model (synchronized access)

• Serves JSON API

• No HTTP needed (server hardwired)

• Blocking calls

• No latency

• One instance per Document23

Page 24: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Haskell Server

24

Page 25: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Model• Undo Manager

• Outline View

• Encoding Callbacks

• Continuation Passing Style

• Performance (outline view, json serialization)

25

Page 26: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

26

Page 27: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

(ObjC) Client-Server• Powers service

• Serializes requests (Object -> JSONValue -> char *)

• Memory management

• Deserializes responses (NSData * -> JSONValue -> Object)

• Logs errors and exceptions

• Updates ModelRevisionCounter

27

Page 28: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

(ObjC) Client-Server• Powers service

• Serializes requests (Object -> JSONValue -> char *)

• Memory management

• Deserializes responses (NSData * -> JSONValue -> Object)

• Logs errors and exceptions

• Updates ModelRevisionCounter

28

Page 29: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Memory Management• ObjC ARC

• HS GC

• Avoidance

• Request: FFI bracket

• Response: NSData allocation, ARC

• Problem: wasting memory (make model strict)29

Page 30: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Exception Handling

• Error reporting

• What happens if ObjC crashes?

• What happens if HS crashes?

• Problem: Lost exceptions

30

Page 31: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

31

Page 32: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Service

32

Page 33: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

33

Page 34: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

NSDocument RAC Write

34

Page 35: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

NSDocument RAC Read

35

Page 36: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

36

Page 37: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

User Interface

37

Page 38: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Server (Haskell)

Client

Service

ApiDocument : NSDocument

WindowController

Document

RAC

38

Unidirectional Data Flow

Page 39: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

In Practice

39

Page 40: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Development Tools• Xcode, -debugger, for ObjC

• Haskell for Mac (Haskell.app IDE) for HS

• Sublime: for shell scrips (Haskell Shelly)

• Instruments

• Threadscope (performance), RTS opts MEM

40

Page 41: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Debugging

41ObjC HS

Page 42: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Testing

• Unit tests for ObjC and HS

• UI tests

• Server interface tests

42

Page 43: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Retrospective

43

Page 44: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Challenges

• Getting started

• Building, Setup, Architecture

• Debugging

• Persistence. All problems solvable.

44

Page 45: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Reflecting• Haskell Language

• Two Languages in one app

• Domain specific

• Cross platform

• Swift

• Cross platform UI Libraries45

Page 47: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Questions?

47

Page 48: Writing a native Mac GUI application in HaskellWriting a native Mac GUI application in Haskell Nikolas Mayr  BOBKonf2017 1 Agenda • JSON Class Generator

Thank You!Feel free to contact me.

Nikolas Mayr <[email protected]>

48