Xcode で GUI アプリ 2

前回まででまずはプロジェクトはできた。

しかし、ViewerController に関しては、Xcode 任せの状態であるため、次に、プロジェクトにこの派生クラスの追加をしよう。

NSWindowController 派生クラスの追加

まず、プロジェクト(本当は「ターゲット」だが)に NSWindowController 派生クラスを追加する。

名前はなんでもいいのだが、諸々の事情で PHWindowController とした。

ファイルが追加できたら、画面左にある(↓)の項目を切り替えて、現在の WindowController を PHWindowController に変更する。

この時点で run させても、変更前と動作は変わらない。

独自機能を追加するため windowDidLoad をオーバーライドする。
なお、Objective-C における override はかなり簡単で、親クラスの同名メソッドを書き換えるだけでいい。

今回は

    [self.window makeKeyAndOrderFront:self];
    [self.window center];

の2行を追加した。

ヘッダファイル PHWindowController.h は以下の通り。

#import <Cocoa/Cocoa.h>

NS_ASSUME_NONNULL_BEGIN

@interface PHWindowController : NSWindowController
//- (instancetype)init;
//@property(strong) NSWindow *window;

@end

NS_ASSUME_NONNULL_END 

PHWindowController.m は以下の通り。

#import "PHWindowController.h"

@interface PHWindowController ()

@end

@implementation PHWindowController

/*
- (instancetype)init
{
  self = [super init];
  return self;
}
 */

- (void)windowDidLoad {
    [super windowDidLoad];
    
    [self.window makeKeyAndOrderFront:self];
    [self.window center];

}

@end

これでランさせると以下のようになる。

変更前には画面やや左下に位置していたウィンドウが中央に配置されるようになった。

ところで、init メソッドは必ずしもいらないようだ。
また、NSWindowController を宣言した時点で window は持っているようで、自分自身のオブジェクトのウィンドウにアクセスする場合は self.window でいいようだ。
こういうクセみたいなものは、やってみないとわからない。

(続く)

Xcode で GUI アプリ

これまで、主にコマンドラインツールを作成してきた。

ある程度、Objective-C の様子もわかったきたと思うので、GUI アプリの作成に手をつけてみよう。

プロジェクトの作成〜実行

Xcode を起動して新しいプロジェクトをつくる。

Command Line Tool ではなく、App の方を選ぶ。

次に Product Name などを決めるダイアログが出現する。

ワイは cocoa-sample としたが、名前などは適当に。

言語は Objective-C で。

悩みどころは、interface の選択で、いくつか候補はある。

アップルのアプリの GUI に関しては、歴史的には、 Nib → Xib → Storyboard → SwiftUI の順番で発展してきた。
(ただし、現状では開発言語を Objective-C を選択した場合は SwiftUI は選べない。なお、Nib は Next Interface Builder から。Xib の X は XML から)

iOS の影響なのか Storyboard で説明してあるサイト・教科書がほとんどだが、今でもレガシーなプロジェクトでは Xib は使われている。さすがに Nib は見かけないが。

GUI のシステムは度々変更されるので、表面的な操作だけではなく、その意味を把握することを意識しておくと少々の変更があっても対応することができると思う。

プロジェクトを作成するといくつかのファイルが自動生成される。

いきなりだが、この時点で run させてみよう。

ここまでの手順が間違ってなければ、以下のようなウィンドウが出現する。

ここまで1行のコードも書かずに Mac ネイティブなウィンドウをディスプレイ上に表示できているわけだから、世間的にはこちらの流儀がメインとなっていくのはわからないでもない。

しかし、である。

知識や理解などがこのレベルに留まっている人は多いようだ。

このレベルだと狙った機能を独自に実装する、というような作業は無理ではなかろうか。

自動生成されたファイルなどの意味をもう少々深掘りしよう。

main.m の意味

main.m の具体的なコードは以下のようになっている。

#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
    }
    return NSApplicationMain(argc, argv);
}

GUI メインで学んできた初学者に「argv って何?」と聞いてもうまく答えられる人はそう多くない。

ワイがまず最初にコマンドラインツールやらポインタの説明をしたのは、ここら辺の理解を深めるためってのもある。

要するにこのコードは argc と文字列配列(のポインタ)argv を NSApplicationMain() に与え、そこからの返り値を待っているという機能をになっている。

では、NSApplicationMain が何かといえば、アプリケーションを管理しているクラスを呼び出す関数ということになる。

ここら辺は日本語記事もあるし、アップル公式の説明でもなんとかなると思う。

ところで、初学者にどの程度まで説明するのか?というのは難しい問題も孕んでいる。

NSApplicationMain にしても、「NS は NextStep に由来する」のようなマメな知識をさしはさんでいるサイトはあるが、「Objective-C/C++ では名前空間の概念がないため、クラスやそのメンバー関数を命名する際には慣例的に大文字2文字を先頭につける」といったところまで説明しているサイトはほぼない

AppDelegate と ViewController

だんだん理解があやしくなってくるのが、AppDelegate や ViewController だろう。

ただ、ちょっと先を急ぎたいので、ここはワイも流させてもらう。

あるアプリが main.m を経て NSApplicationMain で示される何かで管理されているとき、全てが管理されていたのでは、独自実装はできなくなってしまうので、動作の要所要所で独自処理を指示できる箇所が AppDelegate だ、という説明ではどうだろう?

WindowController

cocoa アプリのプロジェクトを作成したとき、AppDelegate と ViewController に対応するファイルは自動で生成される。

が、実際にウィンドウシステムを動作させるとき、これを管理するクラスも必要だ。
結論から先に書くと、これが WindowController クラスで、Xcode 上でも確認できる。

Main.storyboard を選んだ際、これを構成する Scene が表示されるが、Window Controller はしっかりありますよね?

ファイルでは生成されないのだが、裏では動いているという理解でいいと思う。

そのほか

そのままでは機能はしないが、メニュー構造もできている。

つまり、プロジェクトを作成しただけでも、デスクトップアプリに必要な機能はほぼ提供されているのだ。

 

(続く)

Xcode -aggeragate target-

ところで、であるが、アイキャッチの赤い三重丸のようなやつの正式名称を知っているだろうか?

aggeregate target

どことなく射的の的を連想させるアイコン(ターゲット)は aggeregate というらしい。

英単語としての発音は「アーグリゲイト」、一般的な意味は「集約する、合計する」だ。

日本語の情報はほとんどなく

ライブラリ・SDKにSwiftLintを導入するベストプラクティス

でかろうじて触れられているのみ。

aggregate target を生成するのもややクセがあって、

File -> New -> Target…

として(↓)、

ダイアログを表示させ iOS や macOS ではなく other の方を選ぶ。

これは調べないと分かりませんね。

参考

その他、Xcode やビルドシステムについて。

・cmake 単体で iOS のプロジェクトを取り扱う。

cmakeを使ってxcodeを使わずにiosアプリを作成する

・cmake で Xcode のプロジェクトファイルを生成する。

CMakeとIDEを連携させる

help によれば cmake で framework を直接生成できるらしいのだが、試したことはない。
(→結局、試しました

余談 -External Build System-

ところで、アーグリゲイトなターゲットを作成する際、こういう画面が出てくる。

気になるのは External Build Sysytem だと思うが、イマイチ使い方がわからない。

デフォルトだと make を使うように設定されているのだが、aggregate ターゲットでもいけるはずだが???

余裕があったら、調べます。

余談 Xcode での C++ 標準ライブラリのヘッダーファイルの置き場所

Xcode14 では

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1

です。

よく移動になるみたいですね。

標準ライブラリのヘッダーファイルが見つからない場合は、上のフォルダを header search paths に設定する。

 

M1/M2 Mac で eclipse を使う

M1 Mac で Java 開発用に eclipse を導入しようとあちこち調べたのだが、なんか筋悪の指南が多いのでメモ的にまとめ。

筋悪というのは、「eclipse の日本語版は Intel Mac 向けしかないので、それを使いましょう」的なものがほぼ全てだったから。

そんなに日本語化って重要?

多くのユーザーがいると思われる Pleiades All in One (いわゆる eclipse の日本語版)は、確かに現時点(2022/11)では Intel Mac 向けのバージョンしか上がってないのだが、公式サイトには既に M1/M2 向けのコンパイル済み eclipse がダウンロード可能になっているから。

ここで Download AArch64 を選べば、apple シリコン向けの eclipse のダウンロードが始まります。

思うに、Pleiades のは、ちょっとやり過ぎているところがあって、例えばマルチユーザー環境でこのバージョンを使うとたぶんアプリ自体が落ちます(少なくとも私の環境では落ちた)。

一方、こちらのバージョンは、JRE のバージョンやインストール先の指定もできるので、自分のホームにインストールしておけば、他のユーザーに迷惑をかけずに使えます。しかも arm ネイティブで。

Hello, eclipse

インストールが済んだら、まずはハロワ的なやつ。

今回は maven プロジェクトをチョイス。

今回は pom.xml の中身は手動で設定したが、多分、もっと上手いやり方もあるんだろう。

いつものコードを実装して run 。

コンソール出力に

Hello, eclipse

と出て、まずは一安心。

 

(続く)