カプチーノの紹介

カプチーノフレームワークは、デスクトップWebアプリケーションを作成できる独自のテクノロジーです。 DOMを抽象化し、代わりにCocoaのようなAPIを提供します。 CSSレイアウトとクロスブラウザの問題をいじる代わりに、静的ページではなく、アプリケーション開発専用に設計されたインターフェイス、Mac OS XおよびiOSから取得したインターフェイスを使用します。

ロシア語ではカプチーノに関するトレーニング資料がほとんどないことに気付き、ギャップを埋めることに決めました。 このエッセイは、読んだ後すぐに最初のカプチーノアプリケーションの開発を開始できるように設計されています。 Akshellプロジェクトのオンライン開発環境を実装するツールを探していたときに、フレームワークに出会いました。 ブラウザウィンドウで動作する完全に機能するIDEを作成する必要があり、Cappuccinoは素晴らしい仕事をしました。

物語


2008年、Francisco Tolmaski、Tom Robinson、およびRoss Boucher(FranciscoとRossは元Appleの従業員)が280 Northを作成し、プレゼンテーションプレゼンテーションWebアプリケーションである280 Slidesを立ち上げました。 ルックアンドフィールにはまだ感銘を受けますが、それは単なる非現実的なものでした。 さらに、280 Slidesは独立した製品ではなく、新しいWebフレームワークであるCappuccinoの機能のデモにすぎませんでした。

その年の9月4日に、カプチーノはLGPLライセンスの下で公開され、すぐにGitHubでヒットしました。 フレームワークの周りで、製品でそれを使用するプログラマーのコミュニティが形成されました。 それ以来、このコミュニティは成長してきており、カプチーノの開発にますます関与しています。

2009年、280 Northは新製品Atlasを発表しました。これは、画期的なテクノロジーであることが証明されました。 AtlasはWebアプリケーション用のInterface Builderに類似しています。マウスを使用してインターフェイスを描画し、ライブラリから必要なコンポーネントをドラッグできます。 数分の作業は、CSSでの1日の苦痛よりも印象的な結果をもたらします。 カプチーノとは異なり、Atlasはクローズド有料プログラムです。ベータ版をダウンロードするには20ドルを支払う必要があります。 このエッセイはカプチーノに捧げられているので、アトラスの詳細は説明しません。 インターフェースを作成する際に多くの時間を本当に節約し、異なるバージョンのブラウザーとの闘争ではなく、使いやすさに集中することができるとしか言えません。

カプチーノとアトラスが急速に発展したのは、2010年の夏に、モトローラがすべての資産とともに280ノースを購入し、噂によると2,000万ドルを支出したためです。 購入の公式目的は、Androidプラットフォームでの開発技術の開発です。 多くの邪悪な言語がカプチーノの死について語り始めましたが、6か月が経過して以来、フレームワークは積極的に開発され、2月23日にバージョン0.9がリリースされました。

したがって、カプチーノはWebアプリケーションを作成するための最も先進的なテクノロジーの1つであり、その開発は大企業によって提供されています。 すべてのWebプログラマーが勉強するか、少なくともフレームワークに慣れるのに役立ちます。始めましょう。

理論


カプチーノの主な機能は、カプチーノ専用に作成されたObjective-J言語です。 Objective-CはCのJavaScriptと同じアドオンです。私にとっては、多くの人がそうであるように、最初はオブジェクト指向のアドインがそれ自体がオブジェクト指向の言語で作成された理由は完全には分かりませんでした。 ただし、これは非常に理にかなっています。

まず、Objective-Jのおかげで、CappuccinoはCocoa APIを完全に繰り返します。 これは、トピックや創造的な処理のファンタジーではなく、関数のシグネチャに至るまでの単なる繰り返しです。 このため、Mac OS XとiOSで作業しているプログラマーは簡単にWeb開発に切り替えることができます。 すべてのAPIの利便性は、NeXTSTEP OS以降のデスクトップでの長期使用により検証されています。 最後に、フレームワークを使用すると、 Cocoaのドキュメントを正常に使用できます 。これは、 Doxygenの品質と精緻において、 カプチーノのドキュメントを大きく上回ります。

第二に、柔軟性の欠如がプラスになる場合があります。 ほとんどのプログラマーは、私が今大きな異端を表明していると考えるので、すぐに言い訳を始めます。 設計者は、ネットやその他の人為的な制約を導入することで設計を改善できることを知っています。 CappuccinoのObjective-Jインターフェイスは、JavaScriptでできることと比較すると、一見すると不器用で前向きです。 結局のところ、 ターゲットアクションパラダイムの代わりに、明示的なゲッターとセッターの代わりに、クロージャーを使用することができました__defineGetter____defineSetter__ 、角括弧、おなじみのポイントの代わりに。 そして最悪の部分:Objective-Jメソッドはファーストクラスのオブジェクトではありません!

カプチーノと協力した後、私はこのアプローチのメリットを実感しましたが、それは欠点の直接的な結果です。 より厳格なオブジェクトモデルを使用すると、互いに埋め込まれた関数の混乱にinれずに、コードをより明確に構成できます。 長く意味のある名前を使用すると、Cocoaクラス階層を処理できます。通常、1つのクラスには多数のメソッドがあります。 ユビキタスなゲッターとセッターにより、Key-Value Coding、Key-Value Observing、およびKey-Value Bindingの実装が可能になります。これは、複雑なユーザーインターフェイスを作成するというアイデアに革命をもたらします(残念ながら、このエッセイにはそれらを説明する十分なスペースがありません)。

カプチーノで作成したアプリケーションの外観に魅了されたため、カプチーノを使い始めました。 今、私は本当の強みがそのAPIにあることを理解していますが、それは最初はひどく思えました。 したがって、フレームワークの最終的な判断を下す前に、フレームワークの哲学を認識することをお勧めします。

Objective-Jのレビューを始めましょう。 彼がJavaScriptにもたらす主なものはクラスです。 @implementationを使用して定義されます:

  @implementation Person:CPObject
 {
     CPString名@accessors;
 }

 (id)initWithName:(CPString)aName
 {
     if(self = [super init])
         name = aName;
    自己を返す;
 }

 (人)personWithName:(CPString)aName
 {
     return [[Person alloc] initWithName:aName];
 }

 @end 

@implementation@end間はクラスの説明です。 Personクラスは、Cappuccinoクラス階層の最上位であるCPObject継承します。 次に、クラスメンバー変数を中かっこで宣言します。 name -getterおよびsetterが自動的に生成される文字列メンバー変数( @accessorsおかげ)。 Objective-Jでアクセサに名前を付けるためのルールは、やや非標準です-これはnameおよびsetName: この形式は、次のように順守する必要があります。 カプチーノの内部メカニズムはそれに依存しています。

Objective-Jオブジェクト間の相互作用は、この手法がSmalltalk言語で初めて登場したメッセージ転送によって発生します 。 構文的には、次のようになります。

  [オブジェクトメッセージ]
 [メッセージobjectParameter:値]
 [パラメーター1のメッセージオブジェクト:値1パラメーター2:値2]
 ... 

たとえば、 Personクラスのオブジェクトのゲッターとセッターを呼び出すと、次のようになります。

  var name = [aPerson name];
 [aPerson setName:” Vasya”]; 

メソッドは、 @endキーワードの前のメンバー変数の後に宣言されます。 クラスメソッドはプラスで始まり、クラスインスタンスメソッドはマイナスで始まります。

Objective-Jでクラスのインスタンスを作成するには、2つの段階があります。最初に、このクラスのallocメソッドが初期化されていないオブジェクトを作成し、次にコンストラクター(initメソッド)が初期化します。 多くの場合、このプロセスを簡素化するクラスメソッドが定義されていますpersonWithName:はそのようなメソッドの例です。

Objective-Jのコンストラクターの名前は、通常initという単語で始まりinit 。 各コンストラクターは、最初にスーパークラスのコンストラクターを呼び出す必要があり、次に初期化してselfを返します。 設計エラーは、 nil値を返すことで通知されます(はい、Objective-Cの作成時に、例外はまだ流行していなかったため、Cocoa、およびその結果、Cappuccinoは例外を処理しません)。

スタイルの統一のために、Objective-JはObjective-Cから取得した3つの変数を定義します。これらはnilYESおよびNOです。 これらはそれぞれnulltrueおよびfalseと同一です。 カプチーノコーディングスタイルガイドラインでは、これらの使用を推奨しています。

このエッセイの多くの読者のように、Objective-Cを使用したことはないので、クラスが@implementationではなく@implementationで定義されている理由は完全には@implementationません@class 。 特に好奇心が強い人のために:Objective-CはCのアドオンとして、宣言ファイル(ヘッダーの* .h)と定義ファイル(メッセージの* .m)を使用するため、クラスを宣言( @interface )および定義( @implementation )する必要があります。 Objective-Jは宣言を必要としないため、 @implementationのみ@implementationます。

練習する


カプチーノをインストールします。 Windowsを使用している場合、最初にCygwinをインストールする必要があります (不快な状況)。 他のすべての人と前のステップをまだ決めている人は、 Cappuccino Starter Packageをダウンロードして、その中のbootstrap.shスクリプトを実行するだけです。

インストール後、cappユーティリティがシステムに表示されます。 例として、Twitterで検索するためのアプリケーション(サプライズ!)を作成します。 生成します:

  capp gen "Twitter Search" 

表示されるフォルダーには、多数のファイルがあります。index-debug.htmlとAppController.jに興味があります(* .jはObjective-Jコードの標準ファイル拡張子です)。

index-debug.htmlを開きます。 Google Chromeの厳格なセキュリティポリシーでは、Cappuccinoがファイルを操作するときに必要なファイルをダウンロードできません。//プロトコル、Webサーバーを上げる必要があります。他のすべてのブラウザーでは、Hello Worldアプリケーションが動作します。 CappuccinoはJavaScriptでObjective-Jコードをブラウザーで直接コンパイルするため、開発中にページを更新するだけで、再構築の心配はありません。 アプリケーションの「戦闘」バージョンを事前にコンパイルして、ダウンロードを高速化できます。

開発に進みます。 AppControllerクラスは、ファイルAppController.jで定義されます。Objective-Jでは、各クラスのコードを同じ名前のファイルに配置するのが一般的です。 Cappuccinoは起動時にAppControllerインスタンスを1つ作成します。アプリケーションを初期化し、その後の作業を管理する必要があります。

クラスを定義する前に、Cappuccinoの2つの主要部分であるFoundationAppKitをインポートします。 Foundationはビジネスロジックを提供するクラスが含まれており、 AppKitはユーザーインターフェイスクラスのライブラリです。

  @import <Foundation / Foundation.j>
 @import <AppKit / AppKit.j> 

@importキーワードに@import指定されたファイルが@importれます。 Cの場合と同様に、山括弧でパスを指定すると、現在のフォルダー内の二重引用符を使用している場合、ファイルはシステムフォルダーで検索されます。

applicationDidFinishLaunching:メソッドapplicationDidFinishLaunching:は、アプリケーションの起動直後にすべてのオブジェクトで呼び出されます。 Cappuccinoメソッドの意味のある名前は、フレームワークに慣れていない人でもコードを理解できるようにするため、非自明な場合にのみ説明します。 カプチーノがキーストロークを保存する可能性は低いので、少なくとも私に保存してください。

アプリケーションを初期化するために、ウィンドウとテキストフィールドを作成します。

  var window = [[CPWindow alloc] initWithContentRect:CGRectMake(100、100、250、70)
                                          styleMask:CPTitledWindowMask]、
     contentView = [window contentView]、
     textField = [[CPTextField alloc] initWithFrame:CGRectMake(25、20、200、30)]; 

JavaScript関数CGRectMake(x, y, width, height)は、コントロールが配置される長方形を記述します。 contentViewメソッドは、ウィンドウの内部領域のビューを返します。

以前は、文字列の長さ制限である80文字を熱心に支持していました。 Cappuccinoでこのルールを適用すると、コードが判読不能な混乱に変わるため、ほとんどの開発者は、Objective-JとObjective-Cの両方で作業するときに自分自身を制限しません。 唯一の例外はGoogle ガイドラインですが、彼とGoogleです。

次に、テキストフィールドを編集可能にし、フレームを追加しましょう。

  [textField setEditable:YES];
 [textField setBezeled:YES]; 

ターゲットとアクションの設定、つまり フィールドでEnterボタンが押されたときに呼び出されるオブジェクトとメソッド:

  [textField setTarget:self];
 [textField setAction:@selector(didSubmitTextField :)]; 

@selector 、メソッドを渡された値に変換するために使用されます。

ウィンドウにフィールドを追加してフォーカスします。

  [contentView addSubview:textField];
 [window makeFirstResponder:textField]; 

最後に、ウィンドウを表示します。

  [ウィンドウ中央];
 [window setTitle: "Twitter Search"];
 [window orderFront:self]; 

アプリケーションの初期化は終了しました。Enterキーを押したときの反応を確認します。 didSubmitTextField:メソッドdidSubmitTextField:

  -(void)didSubmitTextField:(CPTextField)textField
 {
     var searchString = [textField stringValue];
     if(!searchString)
        帰る
     [[[SearchWindowController alloc] initWithSearchString:searchString] showWindow:nil];
     [textField setStringValue: ""];
     [[textField window] makeKeyAndOrderFront:nil];
 } 

テキストフィールドの値を抽出し、空でない場合はSearchWindowControllerインスタンスを作成し、ウィンドウを表示し、テキストフィールドを空にして、ウィンドウを前に押します。 小さなことは、 SearchWindowControllerクラスを開発することです。

ファイルSearchWindowController.jを作成し、 CPWindowControllerからクラスを継承します。

  @implementation SearchWindowController:CPWindowController
 {
 }

 @end 

ウィンドウを作成し、Twitterにリクエストを行うコンストラクターを定義します。

  -(id)initWithSearchString:(CPString)searchString
 {
     if(self = [super init]){
         var window = [[CPWindow alloc] initWithContentRect:CGRectMake(10、30、300、400)
                                                  styleMask:CPTitledWindowMask |  CPClosableWindowMask |  CPResizableWindowMask];
         [ウィンドウsetTitle:searchString];
         [self setWindow:window];
         var request = [CPURLRequest requestWithURL: "http://search.twitter.com/search.json?q=" + encodeURIComponent(searchString)];
         [CPJSONPConnection sendRequest:リクエストコールバック: "callback"デリゲート:self];
     }
    自己を返す;
 } 

最後に、Twitterから応答ハンドラーを作成します。

  -(void)接続:(CPJSONPConnection)接続didReceiveData:(オブジェクト)データ
 {
     var contentView = [[self window] contentView];

     if(data.results.length){
         var bounds = [contentView bounds]、
             collectionView = [[CPCollectionView alloc] initWithFrame:bounds];
         [collectionView setAutoresizingMask:CPViewWidthSizable];
         [collectionView setMaxNumberOfColumns:1];
         [collectionView setMinItemSize:CGSizeMake(200、100)];
         [collectionView setMaxItemSize:CGSizeMake(10000、100)];

         var itemPrototype = [[CPCollectionViewItem alloc] init];
         [itemPrototype setView:[TweetView new]];
         [collectionView setItemPrototype:itemPrototype];
         [collectionView setContent:data.results];

         var scrollView = [[CPScrollView alloc] initWithFrame:bounds];
         [scrollView setAutoresizingMask:CPViewWidthSizable |  CPViewHeightSizable]
         [scrollView setDocumentView:collectionView];
         [contentView addSubview:scrollView];
     } else {
         var label = [CPTextField labelWithTitle: "ツイートなし"]、
             boundsSize = [contentView boundsSize];
         [ラベルsetCenter:CGPointMake(boundsSize.width / 2、boundsSize.height / 2)];
         [ラベルsetAutoresizingMask:CPViewMinXMargin |  CPViewMaxXMargin |  CPViewMinYMargin |  CPViewMaxYMargin];
         [contentView addSubview:label];
     }
 } 

ツイートを表示するには、ライブラリクラスCPCollectionViewCPCollectionViewItemおよびCPScrollViewます。 ただし、 TweetViewクラスTweetView個別に定義TweetView必要があります。

コード内でsetAutoresizingMask:メソッドの呼び出しがいくつかあることに気づいたかもしれません。 もちろん、既にそうしているのでない限り、この方法はCSSの位置付けを永遠に呪います。 カプチーノのコントロールの配置は非常にシンプルでエレガントなので、子供でも操作できます。

TweetViewクラスを処理するために残ります。

  @implementation TweetView:CPView
 {
     CPImageView imageView;
     CPTextField userLabel;
     CPTextField tweetLabel;
 }

 -(void)setRepresentedObject:(id)ツイート
 {
     if(!imageView){
         imageView = [[CPImageView alloc] initWithFrame:CGRectMake(10、5、48、48)];
         [self addSubview:imageView];

         userLabel = [[CPTextField alloc] initWithFrame:CGRectMake(65、0、-60、18)];
         [userLabel setAutoresizingMask:CPViewWidthSizable];
         [userLabel setFont:[CPFont boldSystemFontOfSize:12]];
         [self addSubview:userLabel];

         tweetLabel = [[CPTextField alloc] initWithFrame:CGRectMake(65、18、-6​​0、100)];
         [tweetLabel setAutoresizingMask:CPViewWidthSizable];
         [tweetLabel setLineBreakMode:CPLineBreakByWordWrapping];
         [self addSubview:tweetLabel];
     }
     [imageView setImage:[[CPImage alloc] initWithContentsOfFile:tweet.profile_image_urlサイズ:CGSizeMake(48、48)]];
     [userLabel setStringValue:tweet.from_user];
     [tweetLabel setStringValue:tweet.text];
 }

 @end 

setRepresentedObject:メソッドは、ユーザー名とツイートを含むアバター画像と2つのタグを作成します。

次に、index-debug.htmlを再度開いて、いくつかの単語を探します。 結果は次のようになります。


完全なサンプルコード表示して テストできます。

次は?


もちろん、このエッセイでは、カプチーノ機能の10分の1を説明することはできませんでした。 ただし、これでアプリケーションの開発を開始する準備ができたと確信しています。これをお勧めします。 知識を深めるには、 カプチーノのドキュメントを使用してください。このトピックに関する一連のスクリーンキャストもお勧めします。 フランシスコ、トム、ロスの巨匠の作品と私の謙虚なエッセイが、あなたの一部が新しい興味深いウェブアプリケーションを作成するのに役立つことを願っています。

Source: https://habr.com/ru/post/J114749/


All Articles