iOSでビジュアル表現プログラミング！「ProcessingKit」のご紹介

# iOSでビジュアル表現プログラミング！「ProcessingKit」のご紹介
皆さん、こんにちは。natmarkです。
今回、[ProcessingKit](https://github.com/natmark/ProcessingKit)というライブラリを作ってみたので、そちらの紹介をします！

## 背景
[Processing](https://processing.org/)というビジュアルデザインに使われるプログラミング言語をご存知でしょうか？

> 『Processing（プロセッシング）は、Casey Reas と Benjamin Fry によるオープンソースプロジェクトであり、かつてはMITメディアラボで開発されていた。電子アートとビジュアルデザインのためのプログラミング言語であり、統合開発環境 (IDE) である。 視覚的なフィードバックが即座に得られるため、初心者がプログラミングを学習するのに適しており、電子スケッチブックの基盤としても利用できる。Javaを単純化し、グラフィック機能に特化した言語といえる。』　- Wikipedia Processing

簡単にいうと、Javaを単純化してグラフィックに特化させた言語がProcessingです。

一般的に **初期化関数( setup 関数)** と **メインループ関数( draw 関数)** という2つの関数を使ってプログラムコードを構成するというスタイルが取られ、 **文法の簡易さ・使いやすさ** からプログラミング学習にもよく用いられています。

自分の所属する大学でも、学部1年生でProcessingの講義があり、
教員が[Processingの本](https://www.fun.ac.jp/news20140508/)を書いてしまうほど盛んに用いられています。

今回、学習コストが低く、書きやすさを重視したビジュアルプログラミングをiOSで行いたいと思い、このProcessingという言語の、文法の書きやすさを取り入れたライブラリを作成しました。

## 作ったもの
![ProcessingKit-Header.png](https://qiita-image-store.s3.amazonaws.com/0/84888/bcd4c36d-d565-7bcb-4025-6cf7215895cd.png)
ProcessingKit: https://github.com/natmark/ProcessingKit

![demo.gif](https://qiita-image-store.s3.amazonaws.com/0/84888/d3794d90-1a57-78ef-b744-6fdae7e47a9e.gif)

Processingらしさを取り入れるために、 `setup` と `draw` という2つの関数を使ってプログラムコードを構成するスタイルを取り入れました。

## Processingでの実装とProcessingKitを用いた実装の比較
以下に、Processingでの実装とProcessingKitを用いた実装の比較を示します。
ProcessingとSwiftを書いたことがあれば、そこまで苦戦せずにProcessingKitを用いた実装ができることがわかると思います。

### Screenshot
![Screenshot.gif](https://qiita-image-store.s3.amazonaws.com/0/84888/8f7dcbc2-96e2-c241-75ff-7906a358fc09.gif)
上のような挙動をするプログラムを、`Processing`と`ProcessingKit`それぞれで実装して見ます

#### Processing
```Java:Ripple.pde
class Ripple {
 	float x = 0.0;
 	float y = 0.0;
 	float size = 0.0;
 	Ripple(float x, float y, float size) {
    	this.x = x;
    	this.y = y;
    	this.size = size;
  	}
}

ArrayList<Ripple> ripples = new ArrayList<Ripple>();

void setup() {
  size(375, 667);
}

void draw() {
	background(255, 255, 255);

    noFill();
    stroke(255, 0, 0);
    strokeWeight(1.0);

    ArrayList<Ripple> removes = new ArrayList<Ripple>() ;

    for(Ripple ripple : ripples){
        ripple.size = ripple.size + 5;
        ellipse(ripple.x, ripple.y, ripple.size, ripple.size);
        if(ripple.size >= 1000){
          removes.add(ripple);
        }
    }

    for(Ripple ripple : removes){
    	ripples.remove(ripple);
    }

    fill(0);
    textAlign(CENTER);
    textSize(20);
    text("Touch Me !!", width / 2, height / 2);
}

void mousePressed() {
	Ripple ripple = new Ripple(mouseX, mouseY, 0);
	ripples.add(ripple);
}
```

#### ProcessingKit

```Swift.RippleView.swift
import ProcessingKit

class Ripple {
    var x: CGFloat = 0.0
    var y: CGFloat = 0.0
    var size: CGFloat = 0.0
    init(x: CGFloat, y: CGFloat, size: CGFloat) {
        self.x = x
        self.y = y
        self.size = size
    }
}

class RippleView: ProcessingView {

    var ripples: [Ripple] = []

    func setup() {
        // The setup() function is run once, when the program starts.
    }

    func draw(){
        // Called directly after setup(), the draw() function continuously executes the lines of code contained inside its block until the program is stopped or noLoop() is called.
        background(255, 255, 255)

        noFill()
        stroke(255, 0, 0)
        strokeWeight(1.0)

        for ripple in ripples {
            ripple.size = ripple.size + 5
            ellipse(ripple.x, ripple.y, ripple.size, ripple.size)
        }
        ripples = ripples.filter { $0.size < 1_000 }

        fill(UIColor.black) //UIColorも使える
        textAlign(.center)
        textSize(20)
        text("Touch Me !!", width / 2, height / 2)
    }

    func fingerTapped() {
        let ripple = Ripple(x: touchX, y: touchY, size: 0)
        ripples.append(ripple)
    }
}

```

一部、Swiftらしさを取り入れた実装をしていて、`fill`や`stroke`では`UIColor`が使用できたり、`mode`の指定で`enum`を使用していたりします。

## 導入
`Carthage`もしくは`CocoaPods`を使用して導入することができます。

### Carthageを利用する場合
```:Cartfile
github "natmark/ProcessingKit" ~> 1.0.0
```
```zsh:
$ carthage update --platform iOS --no-use-binaries
```
参考: https://qiita.com/yutat93/items/97fe9bc2bf2e97da7ec1

Carthageを使用したサンプルプロジェクト: [PKExample](https://github.com/natmark/PKExample)

### CocoaPodsを利用する場合
```zsh:
$ pod init
```
```rb:Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'PKPodsExample' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for PKPodsExample
  pod "ProcessingKit","1.0.0"
end
```
```zsh:
$ pod install
```

CocoaPodsを使用したサンプルプロジェクト: [PKPodsExample](https://github.com/natmark/PKPodsExample)

## 実装
### 1. ProcessingViewを継承した、スケッチ用のViewを作成する

```Swift:CustomView.swift
import ProcessingKit

class CustomView: ProcessingView {
    func setup() {
        // 初回に1回だけ実行したいコードを記述
    }

    func draw() {
        // 毎フレーム実行したいコードを記述
    }
}
```
### 2-a. Storyboardから作成する場合
- UIImageViewのカスタムクラスに上で作成した`CustomView`を指定
<img width="572" alt="スクリーンショット 2017-10-01 18.41.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/84888/194c55b0-5129-ee9e-5bdf-0c47151e5312.png">

- コードにIBOutletで紐づける

```Swift:ViewController.swift
 @IBOutlet weak var sampleView: SampleView!
```

### 2-b. コードから作成する場合
```Swift:ViewController.swift
  override func viewDidLoad() {
     super.viewDidLoad()     
     let customView = CustomView(frame: self.view.frame)
     self.view.addSubView(customView)
 } 
```

あとは、先ほど作成した`CustomView`の`setup()`と`draw()`内にコードを書くことで、画面に反映されるようになります。

## サンプルについて
本体ライブラリにいくつかサンプルを作成して置いてありますので、参考にしていただければと思います。

- ProcessingKitExample: https://github.com/natmark/ProcessingKit/tree/master/ProcessingKitExample

![Example.gif](https://qiita-image-store.s3.amazonaws.com/0/84888/8eb2f7b7-72c4-7dca-70d7-245c0b2227e8.gif)

## Playgroundについて
ProcessingKitをすぐ試せるように、`Demo.playground`を本体ライブラリに含めています。こちらも合わせて使っていただければと思います。

- `Demo.playground`: https://github.com/natmark/ProcessingKit/tree/master/ProcessingKit/Demo.playground

![Playground.gif](https://qiita-image-store.s3.amazonaws.com/0/84888/9e1b08c6-26d0-76fa-3a50-0336d95b4780.gif)



## まとめ
比較的簡単に導入でき、iOSで簡易にビジュアルプログラミングができることを目指して開発を始めた`ProcessingKit`ですが、本家の`Processing`に比べるとまだまだ足りない関数も多く、最新バージョン`0.4.0`でようやく基本的な関数が揃ったかな？という温度感になっています。

[2018/01/04更新] Swift4・OS X対応した `ProcessingKit 1.0.0` を無事公開できました！

学業の傍にはなってしまいますが、今後もちまちま作っていく予定ですので、よろしくお願いします :bow: