Swiftエンジニアが今週末キャッチアップしたいサンプルコードまとめ


`Swift`が発表されてから、数日経過しましたがすでにたくさんのコードがGithubに上がっています。`Swift`を始めたいエンジニアが参考になるサンプルをピックアップしてみました。
自分も今週末に珈琲を片手にコードを読んでみようと思います。

![Search_·_swift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/f81aaf84-74e7-e74c-53d4-a53db4e5e548.jpeg "Search_·_swift.jpg")

- [Githubの検索結果URL](https://github.com/search?l=Swift&o=desc&q=swift&ref=cmdform&s=stars&type=Repositories)

# [FlappySwift 4,700★](https://github.com/fullstackio/FlappySwift)

半日くらいで作られたFlappy Birdのクローンです。
`SpriteKit`を利用していて、メインのゲームロジックは２００行弱ほどで書かれています。
`Swift`でシンプルなゲームを作成するのに参考になります。

![fullstackio_FlappySwift.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/7e6d454e-153d-5af5-7200-451a803895a4.jpeg "fullstackio_FlappySwift.jpg")

[GameScene.swift](https://github.com/fullstackio/FlappySwift/blob/master/FlappyBird/GameScene.swift) 一部抜粋

```	JavaScript
//
//  GameScene.swift
//  FlappyBird
//
//  Created by Nate Murray on 6/2/14.
//  Copyright (c) 2014 Fullstack.io. All rights reserved.
//

import SpriteKit

class GameScene: SKScene {
    var bird = SKSpriteNode()
    var skyColor = SKColor()
    var verticalPipeGap = 150.0
    var pipeTextureUp = SKTexture()
    var pipeTextureDown = SKTexture()
    var movePipesAndRemove = SKAction()
    
    override func didMoveToView(view: SKView) {
        // setup physics
        self.physicsWorld.gravity = CGVectorMake( 0.0, -5.0 )
        
        // setup background color
        skyColor = SKColor(red: 81.0/255.0, green: 192.0/255.0, blue: 201.0/255.0, alpha: 1.0)
        self.backgroundColor = skyColor
        
        // ground
        var groundTexture = SKTexture(imageNamed: "land")
        groundTexture.filteringMode = SKTextureFilteringMode.Nearest
        
        var moveGroundSprite = SKAction.moveByX(-groundTexture.size().width * 2.0, y: 0, duration: NSTimeInterval(0.02 * groundTexture.size().width * 2.0))
        var resetGroundSprite = SKAction.moveByX(groundTexture.size().width * 2.0, y: 0, duration: 0.0)
        var moveGroundSpritesForever = SKAction.repeatActionForever(SKAction.sequence([moveGroundSprite,resetGroundSprite]))
        
        for var i:CGFloat = 0; i < 2.0 + self.frame.size.width / ( groundTexture.size().width * 2.0 ); ++i {
            var sprite = SKSpriteNode(texture: groundTexture)
            sprite.setScale(2.0)
            sprite.position = CGPointMake(i * sprite.size.width, sprite.size.height / 2.0)
            sprite.runAction(moveGroundSpritesForever)
            self.addChild(sprite)
        }
        
        // skyline
        var skyTexture = SKTexture(imageNamed: "sky")
        skyTexture.filteringMode = SKTextureFilteringMode.Nearest
        
        var moveSkySprite = SKAction.moveByX(-skyTexture.size().width * 2.0, y: 0, duration: NSTimeInterval(0.1 * skyTexture.size().width * 2.0))
        var resetSkySprite = SKAction.moveByX(skyTexture.size().width * 2.0, y: 0, duration: 0.0)
        var moveSkySpritesForever = SKAction.repeatActionForever(SKAction.sequence([moveSkySprite,resetSkySprite]))
        
        for var i:CGFloat = 0; i < 2.0 + self.frame.size.width / ( skyTexture.size().width * 2.0 ); ++i {
            var sprite = SKSpriteNode(texture: skyTexture)
            sprite.setScale(2.0)
            sprite.zPosition = -20;
            sprite.position = CGPointMake(i * sprite.size.width, sprite.size.height / 2.0 + groundTexture.size().height * 2.0)
            sprite.runAction(moveSkySpritesForever)
            self.addChild(sprite)
        }
        

    
・・・

```

# [swift-2048 600★](https://github.com/austinzheng/swift-2048)

`Objective-C`で作られた2048のゲームを`Swift`に移植したコードです。
`Enum`のパターンマッチを活用している点が参考になります。
メインのロジックは５００行弱です。

[GameModel.swift](https://github.com/austinzheng/swift-2048/blob/master/swift-2048/Models/GameModel.swift) 一部抜粋

```JavaScript
・・・


// Represents an action applied to a tile; used to generate move orders
enum ActionToken {
  case NoAction(source: Int, value: Int)
  case Move(source: Int, value: Int)
  case SingleCombine(source: Int, value: Int)
  case DoubleCombine(source: Int, second: Int, value: Int)

  // Get the 'value', regardless of the specific type
  func getValue() -> Int {
    switch self {
    case let .NoAction(_, v): return v
    case let .Move(_, v): return v
    case let .SingleCombine(_, v): return v
    case let .DoubleCombine(_, _, v): return v
    }
  }
  // Get the 'source', regardless of the specific type
  func getSource() -> Int {
    switch self {
    case let .NoAction(s, _): return s
    case let .Move(s, _): return s
    case let .SingleCombine(s, _): return s
    case let .DoubleCombine(s, _, _): return s
    }
  }
}

・・・

  // Convert all action tokens into move orders
  func convert(group: ActionToken[]) -> MoveOrder[] {
    var moveBuffer = MoveOrder[]()
    for (idx, t) in enumerate(group) {
      switch t {
      case let .Move(s, v):
        moveBuffer.append(MoveOrder.SingleMoveOrder(source: s, destination: idx, value: v, wasMerge: false))
      case let .SingleCombine(s, v):
        moveBuffer.append(MoveOrder.SingleMoveOrder(source: s, destination: idx, value: v, wasMerge: true))
      case let .DoubleCombine(s1, s2, v):
        moveBuffer.append(MoveOrder.DoubleMoveOrder(firstSource: s1, secondSource: s2, destination: idx, value: v))
      default:
        // Don't do anything
        break
      }
    }
    return moveBuffer
  }

・・・
```

# [swiftz 300★](https://github.com/maxpow4h/swiftz)

`Swiftz`は関数型プログラミングのためライブラリです。
便利な機能が追加されています。

`JSON`のパースはバリューの型を厳密の精査するようになったので、`Objective-C`で記述するよりも冗長になりやすいのですが、このライブラリを利用すると使いやすくなります。

並列処理の記述も、`NSOperation/NSOperationQueue`を利用するよりも書きやすいです。

**JSON:**

```JavaScript
let js: NSData = ("[1,\"foo\"]").dataUsingEncoding(NSUTF8StringEncoding,
                  allowLossyConversion: false)
let lhs: JSValue = JSValue.decode(js)
let rhs: JSValue = JSValue.JSArray([JSValue.JSNumber(1), JSValue.JSString("foo")])
XCTAssert(lhs == rhs)
XCTAssert(rhs.encode() == js)
```

**Concurrency:**

```JavaScript
// we can delay computations with futures
let x: Future<Int> = Future(exec: gcdExecutionContext, {
  sleep(1)
  return 4
})
x.result() == x.result() // true, returns in 1 second

// Channels
let chan: Chan<Int> = Chan()
chan.write(1)
chan.write(2) // this could happen asynchronously
let x1 = chan.read()
let x2 = chan.read()
println((x1, x2)) // 1, 2

// we can map and flatMap over futures
x.map({ $0.description }).result() // "4", returns instantly
x.flatMap({ (x: Int) -> Future<Int> in
  return Future(exec: gcdExecutionContext, { sleep(1); return x + 1 })
}).result() // sleeps another second, then returns 5
```


# [Quick 70★](https://github.com/modocache/Quick)

BDDなテストフレームワークです。
[RSpec](https://github.com/rspec/rspec), [Specta](https://github.com/specta/specta), [Ginkgo](https://github.com/onsi/ginkgo)を参考にしてるそうです。記述は[RSpec](https://github.com/rspec/rspec)によく似ていて、`SPEC`が書きやすそうです。また`Swift`の内部DSLとしての可能性も感じます。

```JavaScript
import XCTest

class PersonSpec: QuickSpec {
    override class var isConcreteSpec: Bool { get { return true } }

    override class func exampleGroups() {
        describe("Person") {
            var person: Person?
            beforeEach { person = Person() }

            it("is happy") {
                XCTAssert(person!.isHappy,
                    "expected person to be happy by default")
            }

            describe("greeting") {
                context("when the person is unhappy") {
                    beforeEach { person!.isHappy = false }
                    it("is lukewarm") {
                        XCTAssertEqualObjects(person!.greeting, "Oh, hi.",
                            "expected a lukewarm greeting")
                    }
                }

                context("when the person is happy") {
                    beforeEach { person!.isHappy = true }
                    it("is enthusiastic") {
                        XCTAssertEqualObjects(person!.greeting, "Hello!",
                            "expected an enthusiastic greeting")
                    }
                }
            }
        }
    }
}
```

# まとめ

上記にピックアップしたコード以外にもたくさん面白そうで勉强になるコードがあるので、皆さんも探してみてください。

# [補足 RSS Reader 50★](https://github.com/wantedly/swift-rss-sample)

筆者が作成した、シンプルなRSSのサンプルです。
`cocoapods`のライブラリを利用して、100行程度で実装しているので、最初にアプリ開発の雰囲気をつかむには参考になるかと思います。

[qiita - SwiftのRSS Readerを100行で作ったよ](http://qiita.com/susieyy/items/749c4ac5d82d765c12c6)


![move](https://github.com/wantedly/swift-rss-sample/raw/master/movie.gif)