0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NSExpressionで加算を行う

Last updated at Posted at 2021-04-16

CoreData周りの技術を使っていると、たまにNSExpressionが利用できると便利そうなケースがありますが、これまでなるべく避けておりました。今回、やっと使い方を調べてテストをパスしたので、似たようなニッチなところで困っている人のために記事を残しておきます。

利用可能なオペレーター

expressionForFunction:arguments:のDiscussionで利用可能なオペレーターが列挙されています。

使い方

FUNCTIONなどで包まず、add:to:(param1, param2)という形式で指定します。

func testAddingTwoNumbersWithExpression() throws {
    let exp = NSExpression(format: "add:to:(1, 2)")
    let intValue = try XCTUnwrap(exp.expressionValue(with: nil, context: nil) as? Int)
    XCTAssertEqual(3, intValue)
}

他のオペレーションの使い方

引数を2つ取るものは同様にxxx:yy:(param1, param2)の記法で、
引数を1つしか取らないものはxxx:(param1)の記法で実装します。

引数が1つの場合のサンプル

func testAbs() throws {
    let exp = NSExpression(format: "abs:(-3)")
    let intValue = try XCTUnwrap(exp.expressionValue(with: nil, context: nil) as? Int)
    XCTAssertEqual(3, intValue)
}

注意点

パラメーターは必ず丸括弧の中に記載してください。そうでないとパースに失敗してエラーを投げます。

どこで使うか

NSBatchUpdateRequestpropertiesToUpdatexcmappingmodelでのmigration時に簡単な処理の実行させるのに使うと便利です。

おまけ: カスタム処理を利用する

カスタム処理はFUNCTIONを利用することで利用可能です。

@objc public extension NSNumber {

    func threeTimes() -> NSNumber {
        return NSNumber(value: self.intValue * 3)
    }

}

// テストターゲット内
func testThreeTimes() throws {
    let exp = NSExpression(format: "FUNCTION(1, 'threeTimes')")
    let result = try XCTUnwrap(exp.expressionValue(with: nil, context: nil) as? NSNumber)
    XCTAssertEqual(result, 3)
}

参考

How to use modulus operator with NSExpression?

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?