新しい世界

Xcode 6.0のBeta版をダウンロードしてみた。

インストール手順は、DMGをダウンロードして、ダブルクリックし、.appをアプリケーションフォルダにドラッグ&ドロップするだけ。もちろん、既存の製品版 Xcode 5.1はそのままとして、別途インストールすることができる。簡単。


Xcode 6.0を起動して、新規プロジェクトを作成してみる。

この画面を見よ。

まるでドラクエ3のROMカセットを手に入れたときのような気分にさせてくれる。

Languageのところで、SwiftかObjective-Cかを選ぶことができる。

Device欄は今までと同じく、iPhone, iPad, Universalであった。

試験運転用のプロジェクトをSwiftTestとして作成。

おお!

ApplicationDelegate.swiftとViewController.swiftが自動生成された。

どうもSwiftにはヘッダと実装ファイルを分ける習慣というのはないようで、ソースファイルの一覧がずいぶんとスッキリ。

以前はSupporting Filesの中に、main.mがあって、その中にmain関数が生成されていたのだが、Swiftではそれも存在しない。

AppDelegate.swiftを開いてみる。

全体的にセミコロンがないので、どこぞのVBRubyのようにも見えるが、関数の戻り値の型指定はC++風にも見える。

ちょっと気になったところにコメントを付加していくが、はてなシンタックスハイライトはまだSwiftに対応してなさそうなので、少々見づらいかもしれない。

AppDelegate.swift

// セミコロンや括弧などが要らないだけで、importの指定はObjective-Cとそう変わらない
import UIKit

// @UIApplicationMainの指定が、Objective-CのUIApplicationMainの呼び出しに相当しているそうだ
// 参考
// http://stackoverflow.com/questions/24020000/subclass-uiapplication-with-swift
@UIApplicationMain

// クラス宣言、コロン(:)に続けて、親クラス, プロトコル1, プロトコル2 ... と記述する。多重継承はできない。
class AppDelegate: UIResponder, UIApplicationDelegate {
                            
    var window: UIWindow?    // 変数型の後ろに ? をつけるのはOptional型。nilを許容するという意味。

    // 以下の定義は、Objective-Cの
    // -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    // と同じで、「引数ラベル 仮引数名 : 型」と指定する。
    // Objective-Cと違うところは、最初のパラメータにも引数ラベルをつけられる。
    // ただし、以下を見る限り、最初のパラメータには引数ラベルをつけない習慣っぽいぞ。
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    // Objective-Cでの変数型 BOOL は、SwiftではBoolで、true, false  (これはC++定数と名前がぶつかっているが大丈夫か?)
    // → 翌日追記:Swiftソース内に自由にC, C++のコードを書けるものだと勘違いしていたが、それはできない。
    // 確実にモジュール分解した上でブリッジングということをするので、Swiftと、C, C++, Objective-Cとで定数名がぶつかることは問題にならない。

    // NSString は、String

    // 翌日追記:その他基本データ型
    // Int, Int8, Int16, Int32, Int64, UInt, UInt8, UInt16, UInt32, UInt64, Float, Double, Character
    // これらはプリミティブ型ではなく、オブジェクト
    
    // その他、FoundationやUIKitなどのクラスの名前は同じっぽい



    // 以下、Objective-CのAppDelegateのデフォルト実装と同じ

    func applicationWillResignActive(application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
}

続けてViewControllerのソースを確認してみる。

ViewController.swift

import UIKit

class ViewController: UIViewController {

    // オーバーライド時は指定が必須
    override func viewDidLoad() {
        // メソッド呼び出しがだいぶ「普通」になった。
        // おそらく多くのひとが慣れ親しんでいる「instanceName.methodName()」で、インスタンス名には、self, superも使える。
        // Rubyと違って、メソッド呼び出しの () は省略できない。まあ、それがいいと思う。
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // 「たぶんこうやればいいんだろうな〜」的なノリで、ちょっとだけはなクソみたいなカスタマイズ・・・
    // ステータスバーを消してみる。
    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}


他、細かい点で言えば、Xcode 5.1, Objective-Cで自動生成されるコードのインデントが一部スペースだったのが、Tabになっている。Tab派の私にはありがたいことだ。


次にストーリーボード。

おや? ビューサイズがおかしいぞ? なぜこんなに太っている・・・。

Xcode 5.1では、3.5インチと4インチを選べるアイコンがあったが、それもない。代わりに、「wAny」「hAny」というのがある。

どうも、Xcode 6.0からは、どのような画面サイズにも対応できるようにビューをレイアウトするのが「標準」、言い換えれば、「義務づけられている」ようだ。たぶん、そのために、iPhoneにもiPadにも合っていないアスペクト比をデフォルトで表示しているのであろう。やりよる。

ちなみに、wAny, hAny というところをクリックすると、3×3の格子から、ストーリーボード上の画面として表示したい矩形を選択できる。

上等だ!

では、さっそく恒例のHello Worldプログラムを作ってみる。


・ラベルを貼り付け、textプロパティを "Hello World" にセット
・画面レイアウト制約として、width, heightを固定で定義
・追加で、Horizontal Center in Container 0とVertical Center in Container 0を追加


レイアウトの具体的手順は過去にupしたAutolayoutの記事参照。

やっててよかったAutolayout。



最後に実行確認。

実行確認時のシミュレーターは、選べる種類が増えて、

iPhone 4s, 5, 5s, iPad2, Retina, Air, Resizable iPhone, Resizable iPad

となっていた。たしか、iPhone 4のサポートは終了だとかなんとか、どこかで見かけた気がする。

せっかくだから、持ってないけど iPhone 5s で・・・

できた!

今回は、Xcode 6.0とSwiftコードの世界を少しだけ探検してみた。

Swiftのコードは自分ではまだほとんど書いていないので、次回はストーリーボードを使わずに、簡単なクラス、簡単な画面を作ってみたいと思う。



あと、FF5 の第3世界のフィールド音楽は好きです。



それでは。
楽しい時間でした!
またの機会を!