この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
前記事、「Xamarin.iOS テンプレート(Single View App)」で紹介した通り、Xamarin.iOSはプラットフォームライブラリを「薄くラッパー」したものになっています。 今回は、殆どの場合、最初の入り口となるであろうシンプルなプロジェクトで、VisualStudio(Xamarin/C#)とXcode(Objective-C及びSwift)の比較をしてみました。
2 プロジェクトの新規作成
(1)Objective-C
新規作成から「Single View Applicaton」を選択すると、ストーリーボードを使用した単一ビューのプロジェクトが作成されます。
プロジェクトのファイルツリーを見ると、主要な5種類のファイルが確認できます。
(2)Swift
プロジェクト作成は同じですが、「Language」で「Swift」を選択すると、Swiftによるプロジェクトになります。
ファイルは、Objective-Cとほぼ同じですが、Mainが無く主要ファイルは4種類になっています。
(3)Xamarin
新規作成から「Single View App(iPhone)」を選択すると、上記と同じくストーリーボードを使用した単一ビューのプロジェクトが作成されます。 ※一番上の「Blank App(iPhone)」はストーリーボードが使用されていません
ソリューションエクスプローラーで確認すると、主要なファイルは、Objective-C/Swiftで見たものと殆ど同じになっています。
各IDEのファイルツリーにおいて、赤字で①〜⑤のナンバーリングをしましたが、以降、この5種類のファイルを比較してみることにします。
3 Main(①)
(1)Objective-C
main.mでは、UIApplicationMainでアプリケーションの初期化が行われています。 UIApplicationMainの第4パラメータにはアプリケーションデリゲートのクラスが指定されますが、ここでは「AppDelegate」を指定してるのが確認できます。
Main.m
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
(2)Swift
Swiftでは、前述のとおりMainとなるファイルはありません。AppDelegate.swiftの「@UIApplicationMain」が同等の意味になります。
AppDelegate.swift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
(3)Xamarin
Main.csでは、UIApplicationクラスのMainメソッドでUIKit関連の初期化が行われています。 Mainメソッドの第3パラメータで、デリゲートクラスの名前「AppDelegate」が設定されています。
Main.cs
using UIKit;
namespace App1 {
public class Application {
private static void Main(string[] args) {
UIApplication.Main(args, null, "AppDelegate");
}
}
}
4 AppDelegate(②)
アプリケーションデリゲートは、アプリケーションの起動や終了や中断などの処理を行います。
(1)Objective-C
AppDelegate.m
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
//アプリの起動時
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
//アプリが非Activeになる直前
- (void)applicationWillResignActive:(UIApplication *)application {
}
//アプリが非Activeになりバックグランド実行になった時
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
//2回目以降の起動時(Backgroundにアプリがある場合)
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
//アプリがActiveになった時
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
//システムからのアプリ終了時
- (void)applicationWillTerminate:(UIApplication *)application {
}
@end
AppDelegateの各メソッドは、コメントに記載したタイミングで呼び出されます。
(2)Swift
Swiftのメソッド名は、Objective-Cと同じです。
AppDelegate.swift
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
return true
}
func applicationWillResignActive(application: UIApplication) { }
func applicationDidEnterBackground(application: UIApplication) { }
func applicationWillEnterForeground(application: UIApplication) { }
func applicationDidBecomeActive(application: UIApplication) { }
func applicationWillTerminate(application: UIApplication) { }
}
(3)Xamarin
AppDelegate.cs
using Foundation;
using UIKit;
[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate {
public override UIWindow Window { get; set; }
public override void OnResignActivation(UIApplication application) { }
public override void DidEnterBackground(UIApplication application) { }
public override void WillEnterForeground(UIApplication application) { }
public override void WillTerminate(UIApplication application) { }
}
Xamarinでは、殆ど同じ名前のメソッドが適宜されており、それをオーバーライドすることで、処理を記述します。
5 Info.plist(③)
AppDelegateの初期化が終了したのちに、最初に表示されるルートビューをストーリーボードで作成した場合、その名前はInfo.plistで指定されます。
(1)Objective-C/Swift
「Main storyboard file base name」で「Main」と指定されており、「Main.storyboard」が使用されます。
(2)Xamarin
「Main Interface」で「MainStoryboard.storyboard」と指定されています。
6 Storyboard(④)
(1)Objective-C/Swift
ストーリーボードを使うと、アプリ画面のUIパーツのレイアウトや画面遷移を視覚的に作成することができます。(Xcode4.2以降の機能) ルートビューのクラス名は、ViewControllerと定義されています。
(2)Xamarin
Xamarinでもバージョン3以降、Storyboardによる画面設計ををVisualStudioから行う事ができるようになりました。 画面の描画に少しタイムラグがあり、逐次Xcodeと通信しながら動作しているいるようです。 ルートビューのクラス名は、RootViewControllerと定義されています。
7 ViewController(⑤)
ビューの表示と管理を担当するオブジェクトです。
(1)Objective-C
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
UIViewControllerのメソッドには、次のようなものがあります。
-(void)viewDidLoad //初回ロードされた時のみ -(void)viewWillAppear:(BOOL)animated //画面が表示される都度 -(void)viewDidAppear:(BOOL)animated //画面が表示された後 -(void)viewWillDisappear:(BOOL)animated //画面が閉じる前 -(void)viewDidDisappear:(BOOL)animated //画面が閉じた後 -(void)viewDidUnload //画面がアンロードされたとき -(void)didReceiveMemoryWarning //メモリ不足時
(2)Swift
Swiftのメソッド名は、Objective-Cと同じです。
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
(3)Xamarin
RootViewController.cs
public partial class RootViewController : UIViewController {
public RootViewController(IntPtr handle) : base(handle) { }
public override void DidReceiveMemoryWarning() {
base.DidReceiveMemoryWarning();
}
public override void ViewDidLoad() {
base.ViewDidLoad();
}
public override void ViewWillAppear(bool animated) {
base.ViewWillAppear(animated);
}
public override void ViewDidAppear(bool animated) {
base.ViewDidAppear(animated);
}
public override void ViewWillDisappear(bool animated) {
base.ViewWillDisappear(animated);
}
public override void ViewDidDisappear(bool animated) {
base.ViewDidDisappear(animated);
}
}
UIViewControllerの継承したRootViewControllerとなっていますが、こちらも、iOSの場合とほぼ同じ名前(アッパーキャメルケースになっている)のメソッドが定義されています。
8 まとめ
今回は、シンプルなプロジェクトを作成した際に生成される5種類のファイルについて、3種類のIDEで比較してみました。 ある程度の法則を見つければ、どの言語のドキュメントを見ても、簡単に変換可能だと思います。 私の場合も、Xamarin.iOSを書く際に、SwiftやObjective-Cの本を参考にしています。