Facebookが公開したiOS向けReactフレームワークComponentKit

![Introducing_ComponentKit__Functional_and_declarative_UI_on_iOS___Engineering_Blog___Facebook_Code.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/bdcf7559-4a58-6a29-4457-4941ffa8456f.jpeg "Introducing_ComponentKit__Functional_and_declarative_UI_on_iOS___Engineering_Blog___Facebook_Code.jpg")


FacebookがiOS向けに新しいフレームワーク`ComponentKit`を公開しました。

> ComponentKit which is now used to render News Feed in the Facebook iOS app.

Facebookアプリのニュースフィード部分はすでに`ComponentKit`を利用しているそうです。

Facebookが提唱している[React](https://code.facebook.com/projects/176988925806765/react/)にインスピレーションを受けたiOSネイティブ向けの実装で、Facebookが合わせて発表したJavaScriptでコーディングする[React Native](http://facebook.github.io/react-native/)とは異なります。


- `UIView`や`UILabel`を直接触ることはありません。`CKComponentViewContext`にラップされます
- `ComponentKit`は`Objective-C++`（C++）で作られています
- `ComponentKit`を利用するには`Objective-C++`で記述します
- Swiftから利用するには`C++`のブリッジができないので簡単ではないようです


[Objective-C++について](http://componentkit.org/docs/why-cpp.html)
------------

http://componentkit.org/docs/why-cpp.html

![ComponentKit___Why_C__.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/8ab12ca3-51c2-4292-1235-ea62904ed49a.jpeg "ComponentKit___Why_C__.jpg")


後述するサープルプロジェクトのコードを見ましたが、一部を`Objective-C++`で記述するだけなので仕切りは高くないように感じました。


ブログ [componentkit.org](http://componentkit.org/)
---


要点がまとまっているので、まずはここから読むのがよさそうです。

![Kobito.Uzdl4M.png](https://qiita-image-store.s3.amazonaws.com/0/4943/2fdad94a-faa7-17eb-85d9-465229421e31.png "Kobito.Uzdl4M.png")


![Kobito.A9yoi2.png](https://qiita-image-store.s3.amazonaws.com/0/4943/8486380e-f91a-4aa5-4c19-ea03f7d8b4cf.png "Kobito.A9yoi2.png")



ドキュメント [Introducing ComponentKit: Functional and declarative UI on iOS](https://code.facebook.com/posts/1415586422080360/introducing-componentkit-functional-and-declarative-ui-on-ios/?__mref=message_bubble)
--------------



公開初日からドキュメントが大変充実しています。

[![ComponentKit___Getting_Started.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/795ae521-36fe-47cf-8ac5-e36e79d92e66.jpeg "ComponentKit___Getting_Started.jpg")](http://componentkit.org/docs/getting-started.html)



Github 
----------

[facebook/componentkit](https://github.com/facebook/componentkit)

`ComponentKit`はOSSでGithub上で開発されています。
もうすでにいくつかPullReqがありました。

[![facebook_componentkit.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/9e052e48-d3d7-e80e-d2ee-baf31f7fd577.jpeg "facebook_componentkit.jpg")](https://github.com/facebook/componentkit)



サンプルアプリを触ってみる
--------------

### 感想

やりたいことに対してコードの記述量が多いなと思いました。`Objective-C`と`Objective-C++`はクラス内でも混ぜて記述できるので使い分けによる冗長なコードにならないと感じました。Swiftから利用できないのが残念です。

### インストール

サンプルプロジェクト[WildeGuess](https://github.com/facebook/componentkit/tree/master/Examples/WildeGuess)を`pod try`で簡単に試すことが出来ます。


```shell
$ pod try ComponentKit
```

うまく動作しない場合は最新の`Cocoapods`にしてみしょう。（ v0.36.0 )
ダウンロードが完了すると自動的にXcodeが立ち上がります。

ソースコードの拡張子に`.mm`のものが見受けられます。


![QuoteModelController_m.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/0fc8af3b-c7ca-b516-fee3-9ad9321bf98d.jpeg "QuoteModelController_m.jpg")



アプリを立ち上げてみると以下のような画面が動作します。Viewをタップするとポップアップが表示されるシンプルなものです。

![iOS_Simulator_-_iPhone_6_-_iPhone_6___iOS_8_1__12B411_.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/5aa28b21-0b7c-6c7a-06cc-54f4b7968ba9.jpeg "iOS_Simulator_-_iPhone_6_-_iPhone_6___iOS_8_1__12B411_.jpg")


ソースコードを除いてみます。`Objective-C`と`Objective-C++`が混ざっていますね。

`QuoteModelController.mm`

```Objective-C
/* This file provided by Facebook is for non-commercial testing and evaluation
 * purposes only.  Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#import "QuoteModelController.h"

#import <UIKit/UIColor.h>

#import "Quote.h"
#import "QuoteDisplayStyle.h"
#import "QuotesPage.h"

@implementation QuoteModelController
{
  NSInteger _numberOfObjects;
}

- (instancetype)init
{
  if (self = [super init]) {
    _numberOfObjects = 0;
  }
  return self;
}

- (QuotesPage *)fetchNewQuotesPageWithCount:(NSInteger)count
{
  NSAssert(count >= 1, @"Count should be a positive integer");
  NSArray * quotes = generateRandomQuotes(count);
  QuotesPage *quotesPage = [[QuotesPage alloc] initWithQuotes:quotes
                                                     position:_numberOfObjects];
  _numberOfObjects += count;
  return quotesPage;
}

#pragma mark - Random Quote Generation

static NSArray *generateRandomQuotes(NSInteger count)
{
  NSMutableArray *_quotes = [NSMutableArray new];
  for (NSUInteger i = 0; i< count; i++) {
    NSDictionary *randomQuote = generateRandomQuoteInfo();
    Quote *quote  = [[Quote alloc] initWithText:randomQuote[@"text"]
                                         author:randomQuote[@"author"]
                                          style:generateStyle(i)];
    [_quotes addObject:quote];
  }
  return _quotes;
}

static NSDictionary *generateRandomQuoteInfo()
{
  NSArray *quotes = quotesList();
  return quotes[arc4random_uniform((uint32_t)[quotes count])];
}

static QuoteDisplayStyle generateStyle(NSUInteger index)
{
  switch (index % 4) {
    case 0:
      return QuoteDisplayStyleFrosted;
    case 1:
      return QuoteDisplayStyleMonochrome;
    case 2:
      return QuoteDisplayStyleWarm;
    case 3:
    default:
      return QuoteDisplayStyleSombre;
  }
}

static NSArray *quotesList()
{
  static NSArray *quotes;
  static dispatch_once_t once;
  dispatch_once(&once, ^{
    quotes = @[
               @{
                 @"text": @"I have the simplest tastes. I am always satisfied with the best.",
                 @"author": @"Oscar Wilde",
                 },
                 ....
               @{
                 @"text":@"It'll be boring when it's not fun any more.",
                 @"author": @"Anonymous",
                 }
               ];
  });
  return quotes;
}

@end

```



開発者のAdam Ernstさん
----------

[@adamjernst](https://twitter.com/adamjernst) をフォローしました。

[![Adam_Ernst__adamjernst_さん___Twitter.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/2c20b7d6-e649-6b97-b55e-f31668a7d884.jpeg "Adam_Ernst__adamjernst_さん___Twitter.jpg")](https://twitter.com/adamjernst)


Objc.io
-------

Adam ErnstさんはObjc.ioにも記事をアップしています。

[objc.io - React-Inspired Views](http://www.objc.io/issue-22/facebook.html)

[![React-Inspired_Views_-_iOS_at_Scale_-_objc_io_issue__22.jpg](https://qiita-image-store.s3.amazonaws.com/0/4943/f4076f9d-28f9-e504-3d88-7d28a5c867e6.jpeg "React-Inspired_Views_-_iOS_at_Scale_-_objc_io_issue__22.jpg")](http://www.objc.io/issue-22/facebook.html)




Refs
----------------


- [objc.io - React-Inspired Views](http://www.objc.io/issue-22/facebook.html)
- [React Nativeがスマホアプリのフロント開発を変えるのか](http://wazanova.jp/items/1676)