linker command failed with exit code 1 (use -v to see invocation)の対処

file too small (length=0) file '/some/file/path' for architecture x86_64
linker command failed with exit code 1 (use -v to see invocation)

command + shift + k

これでだいたい解決する

多分ビルドが失敗したときに、変な風に(0byte)書き換わってるのが原因ぽい

randomなint

var items = [1,2,3]
var randomIndex: Int = Int(arc4random()) % items.count
items[randomIndex]

みたいに使う

OHHTTPStubとXCTestで、モックを使った非同期処理をテストする

通信をモックを使って、実際のサーバーサイドやWebAPIとの通信を行わずにテストする。

import UIKit
import XCTest

class SomeAPIClientTests: XCTestCase {
    let someAPIClient = SomeAPIClient()

    override func setUp() {
        super.setUp()
    }
    
    override func tearDown() {
        super.tearDown()
    }

    func testExample(){
        let obj = SomeObject()
        let stub:NSDictionary = ["id": 1]
        let expectation = self.expectationWithDescription("非同期通信は完了する")
        let stubDesc = OHHTTPStubs.stubRequestsPassingTest({ (request: NSURLRequest!) -> Bool in
            // 通信処理をモックを通して行なうか、の条件。trueを返すときに、モックを通す
            return true
            }, withStubResponse:( { (request: NSURLRequest!) -> OHHTTPStubsResponse in
                //レスポンス
                //失敗させたいときはステータスコードをいじるなどする
                return OHHTTPStubsResponse(JSONObject: stub, statusCode: 200, headers: ["Content-Type" : "text/json"])
            })
        )
        
        someAPIClient.post(obj, callback: {(postedObj, error) -> () in
            XCTAssertNil(error, "Error should be nil.")
            //通信が正常に行われたこと、失敗したことをテストしても意味がないので、実際にはそれぞれのケースで行われる処理をテストする。
            //expectation.fulfill()が呼ばれたことが、このテストの非同期処理が正常に行われたことを意味する。
            expectation.fulfill()
        })
        
        self.waitForExpectationsWithTimeout(5, handler: {(error) -> Void in
            //expectation.fulfill()が呼ばれたタイミングで実行される。
            //ここでOHHTTPStubsを消しておかないと、
            //他のテストの通信もこのテストの設定のモックが使用されてしまう。
            OHHTTPStubs.removeAllStubs()
            return
        })
    }
}

UIViewを45度傾かせる

吹き出しようの「ぺろっ」と出てている三角形を作りたかったので、正方形を45度傾かせて実現しました。 この辺の数学的知識が無いので、解説はできません。

let angle = CGFloat(M_PI * (45) / 180.0)
//miniBoxはUIViewのインスタンス
miniBox.transform = CGAffineTransformMakeRotation(angle)

CoreLocationで国、都道府県、市区町村の取得

import CoreLocation
 
let location:CLLocation = CLLocation(latitude: lat, longitude:lon)
geocoder.reverseGeocodeLocation(location, completionHandler:{(placeMarks, error) -> Void in
  if error == nil {
    if placeMarks.count > 0{
      let placemark: CLPlacemark = placeMarks[0] as CLPlacemark
      println(placemark.ISOcountryCode)     // JP
      println(placemark.administrativeArea)  // 都道府県
      println(placemark.subAdministrativeArea) // 群
      println(placemark.locality) // 市町村区
    }
  }else{
    println(error)
  }
})

コレクションはオプショナル型にしない

Swiftを始めてオプショナル型覚えたてで、オプショナル型使いたい病にかかってしまい、 メソッドの返り値のコレクションデータまでオプショナル型で返していました。

ですが、やっぱアンラップするのがめんどくさい。

そもそも、ArrayにもDictionaryにもisEmptyというメソッドが用意されているのだから、コレクションの中身がない場合を想定したコードを書くなら、オプショナル型を使わずにそれを使うべき。

なので、あるかないかわからないコレクションデータを扱いたい場合、空のコレクションを用意し、ない場合は空のコレクションを返したほうがいい

func getSomething() -> Array<Something> {
  //[Something]()
  items = Array<Something>()
  fetchSomething({(data, error) in
    if error == nil{
       if let unwrappedData = data {
          items.append(unwrappedData)
       }
    }else{
       // error
    }
    return items
  })
}

他にどんな書き方があるんだ、という話でもある 明らかに自分がアホだった

定義済みクラスで「Use of undeclared type "ClassName"」のエラー

とっくに定義済みのクラスなのundeclaredと言われて怒られた。

Use of undeclared type "ClassName"

解決方法

右側の「Taget Membership」でテストターゲットの方にもチェックを入れる。

原因

あるクラスのテストを書こうとクラスが定義されたファイルだけテストターゲットに含めても、そのクラスの中で使われているクラスであれば、そのクラスが定義されたファイルもテストターゲットに含めないとエラーが出る。

これは、ビルド時にも起こる。

自分はそういったケースはテストの時にしか発生しないと思っていたので、ちょっとはまった。