iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
2018年4月4日(水)の夜間、東京都豊島区の池袋コワーキングスペース OpenOffice FORESTにおきまして、「BUKURO.swift 2018-04」を開催致しました。
BUKURO.swiftも浸透して来たようで、先月と同様に多くの方が申し込まれました。
初めて参加される方に、どうやってBUKURO.swiftを知ったのか伺ったところ、会社でmacOSプログラミングで悩んでいたところ、同僚から紹介されたとのこと。
ありがとうございます。
これからもアプリケーション・プログラマの方々が役立つ勉強会になるよう精進いたします!
そして、今回の発表はどれもプログラマの好奇心をくすぐるものでした。
よし、自分も頑張ろう!という気持ちにさせていただきました!
今年に入ってconnpassグループは最も申込者が多いグループに一本化したのですが、NPO法人を解散して任意団体としてスタートするのと、勉強会メンバーも任意団体MOSAの準備チームとしてイベントを主催していくことになったのと、MOXSSGとThe Bash in Tokyoを共催することになり、MOSAのconnpassグループを活性化する必要があるでしょう、ということで、一時的にCocoa勉強会 関東とMOSAのconnpassグループの両方で申し込みページを用意することになりました。
NSMatrixが非推奨になっているそうです。そこで、代替機能として、同じ大きさの矩形を整列させるための支援コードの発表です!
以前、Cocoa勉強会 関東で発表されましたが、その後の状況の変化を加味した発表でした。
自分自身も、その後、経験を積み、前回と比較して理解度も上がり、プログラマの好奇心をくすぐる内容に楽しまさせていただきました。
SwiftのStringがUnicodeに高い割合で準拠しているのは知っていたのですが、例えば、文字をどういう用語で扱っているのか説明できずもどかしかったのですが、拡張書記素クラスタ(CodePoint)というのですね。そして、例えば、RubyはUnicodeスカラーで、JavaはUTF-16、PythonはUTF-8で扱うため、得られる文字列長が異なるとか、macOSのファイルシステムでの文字列がModified NFDとなっている理由。それから得られる日本語としての恩恵。文字の比較でUnicodeの一貫性のなさからNFDで比較すればいいという訳でない事。
曖昧に理解していた事が再確認できて、とても有益でした。
Unityを使った2Dと3DのWebGLアプリのデモです。十分遊べる完成度に驚かされました。やりますね!
iOSアプリケーション開発を主な業務としているが、チームの都合でObjective-Cを選択している。そんなSwiftに不慣れな自分にとって厄介なのはOptional。色んな場面で様々な形式で出てくるため混乱する。そこで自分自身がOptionalを習得するため、自分が見つけられたOptional関連のコードを飼料化してみた。
プログラミングが生まれた頃から、様々な方法で無を表現することが試みられている。
Lispは実装方法によるが内部ではnilを値と要素の二通りがあるようだ。
それと比較して、C言語は質実剛健。簡素で実用的だ。
var a : Int = 1
var b : Int? = 2
a = nil // エラー
b = nil // OK
b = Int(“abcd”) // nil
var c : Optional = 3 // パラメータ付き型指定
SwiftでOptionalといえばInt?と型に?がついた宣言ということになるが、厳密にはパラメータ付き型指定の糖衣構文とうことになる。Optional変数にはnilを代入することが出来るが、Optional出ない型とは異なる型ということになる。
Optional変数に!をつけると、Optionalでない変数に変えられる。Optional変数がnilだったら実行時にエラーとなる。
C言語のポインターに近い挙動ということか。
var a : Int? = 1234
var b : Int = a - 2 // 型が異なるのでコンパイル・エラー
var b : Int = a! - 2 // 開示指定する
a = nil
b = a! - 2 // 実行時エラー
a = 5678
if a != nil {
print(“\(a!)”) // 開示指定が必要
}
print(String(describing: a)) // Debug目的で
C言語のNULLチェックをして利用するというパターン化されたコードをスマートにしたのが、オプショナル束縛構文 か?
var num : Int? = 1234
if let n = num {
print(“\(n)”)
}
if var n = Int(“1234”) {
n += 5678
print(“\(n)”)
}
if let n = Int(“1234”), let m = Int(“5678”) {
print(“\(n + m)”)
}
var a : Int? = 1
while let n = a {
a = nil
}
if分によってインデントが深くなることを避けるため、例えば、関数の先頭でNULLチェックをして、NULLだったら直ぐにreturnするというパターン化されたコードがあるが、これのために用意されたのが、guard文。オプショナル束縛構文の糖衣構文ということのようだ。
guard 条件 else { /* breakやreturn */ }
func demo(_ num:Int?) {
guard let n = num else { return }
print(“\(n)”) // 変数nが使える
}
三項演算子で値がnilなら指定した値を、nilでない場合はその値を返すというパターン化されたコードが必要になると思うが、これについても糖衣構文が用意されている。
let n : Int? = 1234
let m = (n != nil) ? n! : 0
let m = n ?? 0
let a : Int? = nil
let b : Int? = nil
let c : Int? = 3
let = a ?? b ?? c ?? 0 // cの値
Swiftの関数は、C言語と同様に値渡しだが、C++の参照渡しに相当するのがinout引数。
ただ、実引数に&をつけることから、C言語のポインターの値渡しをポインターであることを隠蔽した構文ということかなと思う。
func demo(_ p: inout Int?) {
p = nil
}
var n: Int? = 1234
demo(&n)
print(n ?? “nil”)
func test(_ num: inout Int) {
num = 0
}
n = 5678
test(&n!) // nがnilだと実行時エラー
print(n ?? “nil”)
実引数が計算型プロパティだった場合は、関数内での変更はコピーに対して行われる。
有値オプショナル型 (implicitly unwapped optional) は、オプショナル型だが、値が格納されていることが分かっている場合のための構文。
おそらく、Objective-C / Cocoa との互換性のためのもので、例えば、InterfaceBuilderのOutletなどで利用されいるようだ。
let n : Int! = 1234
print(“\(n)”) // 開示指定は不要
var m : Int! = nil
m += 5678 // 実行時エラー
print(“\(m)”)
自分の調査が足りなかったら申し訳ないで、Swiftが登場した当初、Optional型とはNSObjectを継承したクラスだったと思うが、言語的には曖昧だと思う。このOptional型の定義を厳密にするために用意されたのが、失敗のあるイニシャライザ ということか?
struct Demo {
var a = 0
init?(_ n:Int) {
if n < 0 {
return nil
}
a = n
}
init() {
a = 1234
}
}
var p: Demo = Demo()
var q: Demo? = Demo(5678)
Swiftの言語仕様書のOptionalの章に含まれるものではないようだが、Optionalの話で大事な構文がキャスト演算子だ。列挙してみる。
オプショナル束縛構文は、続けて記述できる。
// 辿っている途中でnilがあれば、
// そこで止まり全体でnilとなる。
if let name = who?.club?.teacher?.name {
print(name)
}
とても違和感を感じる用語がある。それは、『参照渡しだ』。
え!違うだろ?と感じていたが、いい機会なので、調べてみた。
引数と呼ばれるものにどんな種類があるのか、まずは列挙してみる。
関数に渡す値。
sum(1, 2);
関数が受け取った変数。
int sum(int a, int b)
{
return a + b;
}
値が渡される。
渡す値がアドレスの値渡し。
_ ## 参照渡し
変数そのものを渡す。
参照渡しで、内部でアドレス情報を渡す方法。
自分の理解では、初期のプログラミング言語ではローカル変数の実装が困難で、変数はグルーバル。なので、変数渡し。近年の高級言語でローカル変数が実現され、その流れで値渡しが用意されたのかなと思っている。
Pascalでは,値渡し(call by value)と変数渡し(call by variable)が存在し、変数渡しは参照渡しに相当する。
そもそもは、変数渡しの実装方法に参照渡しがある。参照渡しは、変数に対する参照(アドレス情報)を渡す方法だ。
Inside Macintoshは、コードはPascalで記載されているが、それをC言語で利用する場合、varがついた変数渡しの引数は、C言語ではポインターと読み替えていた。
具体的には、Inside Macintoshで以下のようにPascalで説明されていたとする。
PROCEDURE GetPort(VAR port: GrafPtr);
これをC言語では、以下のように読み替える。
void GetPort (GrafPtr *port);
C言語の関数の引数は全て値渡し。K&Rでしっかりと説明されている。
ポインタでアドレスの値を渡すのを参照渡しと呼ぶのは間違いだ。
Javaも全て値渡し。
ポインタ演算ができない、アドレス(参照)の値渡しが利用できるが、これを参照渡しと呼ぶのは、如何なものか。
0'RellyのJavaクイックリファレンスでは、Javaは配列とオブジェクトを参照を通じで扱うと説明されていた。また、参照渡しという言葉と混同しないようにと書かれていた。
参照型の値渡しが参照渡しと勘違いされるのは、仮引数の参照型の中身の値の変更が、実引数側に反映されるからだと思うが、参照先自体の変更ができない。これは、C言語で、引数で渡されたポインターが指す先の値は変えらるがアドレスは変えられない。変えたい場合は、ポインターのポインタを利用するしかないということから分かると思う。
static char a[] = "hello";
static char b[] = "world";
void set_b(char **handle)
{
*handle = b;
}
in t main(int argc, char *argv[])
{
char *ptr = a;
printf("%s\n", ptr);
set_b(&ptr);
printf("%s\n", ptr);
return EXIT_SUCCESS;
}
値渡しに加え、本物の参照渡しが存在する。
void time_two(int& a)
{
a *= 2;
}
また、C++11では右辺値参照・ムーブセマンティクスという所有者の移動が用意されている。
二つの参照渡しの方法が用意されている。
int initializeInMethod = 0; // 初期化が必須
OutArgExample(initializeInMethod);
Console.WriteLine(initializeInMethod);
void OutArgExample(ref int number)
{
number = 44;
}
int initializeInMethod;
OutArgExample(out initializeInMethod);
Console.WriteLine(initializeInMethod);
void OutArgExample(out int number)
{
number = 44; // 代入が必須
}
refは変数が渡されるので、初期化によって値が設定されていない変数はNGだ。
outは値を返すという意味から、初期化は必須でないか、関数内で値を必ず設定しないといけない。
値渡しだが、inoutキーワードをつけると値呼びの結果返し(call-by-value-result)となる。
C言語のポインターの場合と同様に、変数が参照型の場合、参照の値渡しにより値を変更できる。
class Demo {
public var num = 0;
}
func set999(a: Demo) {
a.num = 999;
}
let demo = Demo()
set999(demo)
値呼びの結果返しの例。
func set999(a: inout Int) {
a =999
}
var num = 0
set999(&num)
少し複雑に感じるが、基本、C言語と同様と考えると成る程だ。
2018年4月12日(木)の夜間、東京都新宿区のTHE DUBLINERS’ IRISH PUB 新宿店におきまして、「PubHack.swift 2018-04」を開催致しました。
PubHack.swiftは今期からはじめましたMOSAの新しい形のイベントで、飲み会イベントを通じて、macOS/iOS/tvOS/watchOS/Androidエンジニアの人たちの交流を目的としています。
名前の由来を説明しますと、PubHackは英国 Pub Rock からとりました。
Pubは飲み会、Hackはプログラミング、.swiftはmacOS/iOS/tvOS/watchOS系です。
第一回目の開催ということで、正直、浸透していませんが、それでも参加人数は7名と、予想した人数より多くなり大変嬉しいです。
また、参加された方のバックグラウンドも多彩で、新しいイベントとしては、よかったのではないかと思っています。
純粋な飲み会イベントということで、長々と文章で説明するのも野暮だと思いますが、出てきた話題を何個かピックアップしますと、以下のとおりです。
村上龍さんの超電導ナイトクラブという小説がありましたが、それが再現された感じの楽しい夜でした。
2018年5月11日(金)の夜間、東京都豊島区の池袋コワーキングスペース OpenOffice FORESTにおきまして、「関東swift勉強会2018-05」を開催致しました。
参加された方から、発表を聞くだけですと学ぶのが難しいという意見が出ました。例えば、ペアプログラミングをやってみるのは?というアイディアをいただきました。
次回の六月は合同勉強会『The Bash in Tokyo』ですので、七月の勉強会で何かやってみます。
来月に任意団体MOSAのスタート・イベントとして『The Bash in Tokyo』を予定していました。
このイベント以降は新たな体制で実施するという気持ちでした。
ですので、NPO法人としての最後のSwift勉強会になるという気持ちで開催いたしました。
NPO法人から任意団体に移行するとうことで、無理をしてイベントを主催してきましたが、勉強会の本来の目的としてどうなのかという気持ちが出ていますが、それについては次回以降でお話しいたします。
過去、Cocoa勉強会で発表がありましたが、今回のポイントは、エントリーポイントとなるC言語の関数からSwiftで実装されたコードをどうリンクさせるかで、ドキュメントでの説明がない部分ですが、試行錯誤して発見された方法が発表されました。
「オンラインゲーム・テクニカルオープンカンファレンス #2」で発表されたRUDPを参考にして実装してみた発表です。
技術日誌をつけよう!という内容です。仕事ではつけている方は多いと思いますが、個人の開発でも!
2018年6月15日(金)の夜間、東京都渋谷区のhoops link tokyoにおきまして、「【合同勉強会 WWDC18特集!】The Bash in Tokyo」を開催致しました。
このイベントを企画した意図は、それぞれの専門分野に特化したコミュニティのメンバーが交わることによって化学反応でしたが、予想以上の結果となりました。お互い知らない仲ではないのですが、気づかなったお互いの面白さが確認されたいい夜でした!
任意団体MOSAのスタート・イベントとして企画して、運営しました。
会場も考えられない程、素晴らしい施設でした。
このイベントはMOXSSGが開催されていたものだったのですが、今回、合同で開催させていただき感謝しかありません。
ただ、自分自身も気になっていたことで、後日、MOXSSGの方からも聞かれたのですが、大規模な開催にすることによって、交流会色が強くなっていないか。確かに強くなっていました。
また、当日、準備を手伝ってくれた勉強会の方が、イベント中に、休日の昼間に、しっかりとした勉強会を開催したいという提案を受けました。おそらく、同じことを感じられていたのだと思います。
このイベントは、転機となった感慨深いものとなりました。
WWDC (Worldwide Developers Conference) とは、Appleが毎年6月ごろに一週間かけて開催される開発者向けイベントです。Bash は、WWDC期間中の木曜日の午後に開催される野外パーティです。
WWDCでは、開発者向けにMacやiPhoneの次期OSと、その新機能をプロダクトに組み込むための手法が発表されるのと、Appleのエンジニアに直接疑問をぶつけられるということで、開発者にとって関心が高いイベントですが、近年はiPhoneアプリケーション開発者の増加によって人気が高いイベントとなり、すぐにチケットがソールドアウトとなってしまいます。
そこで、MOXSSG (Mac OS X Server勉強会)では、ほぼ、毎年、WWDCのチケットが買えず、日本残留組となった方々と『The Bash in Tokyo』というイベントを開催していました。
今回、このイベントをより幅広い方が参加できるように、Cocoa勉強会 関東とMOSAと合同で開催することにいたしました。
Cocoaの「逐次検索」を支援するクラスNSTextFinderについての発表です。
たまにmacOSのアプリを作ったりしていますが、NSTextFinderなるクラスがあることを初めて知りました。Cocoa Frameworkは奥深いです。インクリメンタルサーチのUIを容易に実装できるので、データブラウザ系のアプリ開発には役立ちそうです。NSArrayControllerもサポートしているので、Cocoa Bindingとの相性も良さそうです。余談ですが、そのCocoa Bindingの未来が心配です。iOSにも実装されていませんし、いつDeprecatedになってもおかしくないですけど、歴史のある仕組みなのでそう簡単にはAppleも切れないでしょうね。
キーボードのDvorak配列。初期の学習コストが高そうですが、面白いですね。
macOSアプリケーション・プログラマが気になるUIKitとの関係について発表です。
今回も盛りだくさんで楽しませていただきました!
フリープログラマの神田さんからは、最近リリースしたランダム俳句について機能を紹介いただきました。与謝野蕪村、小林一茶などの名句から五・七・五を抜き出し、それぞれをランダムに組み合わせて新しい句をジェネレートするユニークなアプリです。お気に入りの句を登録したり、プリンタで印刷機能も備わっています。初めてSwiftでプログラミングされたそうで、他にも開発中のアプリがあるそうです。次作にも期待しましょう!
飛び入りで自作のアプリについて発表していただきました。ありがとうございます!
自分のような凡人は敵いません。まさかARでプレゼンをされるなんて!
飛び入りでWWDC18のレポートを発表していただきました。ありがとうございます!
『The Bash in Tokyo』という祭りは終わりました。
今後は、地道にコツコツと勉強会を開催することにして、心機一転の第1発目。
予想外だったのは、申し込み人数が多かったことです。
そして、自分の発表、参加された方々が楽しんでくれたようで充実した勉強会となりました。
よかった。ホッ。
この発表があった時点で、VirtualBoxへMojaveをインストールするのは困難でした。
この発表では、インストールに成功したので、その手順を詳細に説明しました。
ちょうど仕事でiPhoneの通信障害を負っていたので、USBで接続されたiOS端末をMacでパケットキャプチャーをする方法を発表した。
発表者は、Objective-Cの専門家だが、仕事の都合でSwiftを利用する機会がするない。
慣れていないので、なかなか、Optionalがマスターできない。
そこで、Optionalに関係することを全て一覧にして、その内容が具体的なコードを簡素な資料にしたので、それを発表した。
この発表は、次の発表と続いていて、勉強会参加者とOptionalについてディスカッションした。
発表会用に用意したコードをもとに、勉強会参加者とディスカッションするという内容だった。
やはり、こういう形式だととても盛り上がる。
参加された方々は楽しめたのでは?
このイベントは、Cocoa.swiftで何度か発表して盛り上げていただいた ぴよまるソフトウェア(AppleScriptの穴) さんのイベントということもありますし、ぴよまるソフトウェア(AppleScriptの穴) さんは、任意団体MOSAの準備チームに参加していただいているのもありますし、任意団体MOSAのイベントということもあり参加してきました。
また、自分自身もAppleScript自体にも興味がありますが、どんな方々がどんな話題で盛り上がっているのかも、気になっていました。
ただ、イベントの内容は、その場で、各人が事例を紹介するなどの形式のため、申し訳ございませんが、上手くメモれていません。申し込みページの内容をそのまま掲載となってしまいました。
AppleScriptについて語ろう! 最新情報紹介や自慢・質問なんでも!
_ # MOSA+Piyomaru Software共催
AppleScriptについてのイベントです。情報共有、質疑応答などを目的とします
Cocoaを一人で勉強するのはつらくて長い道のり...
そんなあなたの
Cocoa.swift
macOSのウィンドウのTabについての発表です。
GDPRで話題になる頻度が上がったプライバシーとセキュリティ。対応は個々でだと思いますが、サーバを利用しないなんて考えられない今のスマートフォン・アプリケーション開発者にとって、何らかの対応が必要になる可能性があります。
今回の発表では、iOSアプリケーション開発に関係がありそうな項目について、開発の現場で話題になっていることを取り上げてみました。
MacintoshのSystem 7で登場したのがAppleイベント。Appleイベントはアプリケーション間コミュニケーション(IAC)のための仕組みです。
また、アプリケーションがOSA (Open Scripting Architecture) に準拠していると、AppleScriptなどのOSA言語で記述されたスクリプトで操作できることになります。
今回の発表では、初期の頃のお話から、基礎的なこと、今のお話まで取り上げてみました。
Macintoshが革新的だったのは、白色背景に黒文字を表示したことです。これは、macOSのAquaにも受け継がれたのですが、MojaveのDark Mode登場により状況が変わりました。説明を信じれば集中したいときはDark Modeが適しているそうです。
真偽はさておいて、Dark Modeに試してみて感じるのは、Dark Modeに完全対応していないアプリケーションが存在すると、画面が見苦しくなるということです。
今回の発表では、Dark Modeへの対応方法を駆け足で紹介してみました。
とても違和感を感じる用語があります。それは、『参照渡し』です。 え!違うだろ?と感じていたのですが、いい機会なので調べてみました。
Cocoaを一人で勉強するのはつらくて長い道のり...
そんなあなたの
Cocoa.swift
ターミナルでgit操作をしている際に、プロンプトにgitの状態が表示されると便利だ。
Appleが提供する開発環境は、App Store経由で入手できるXcodeをインストールするだけで完了するが、開発者サイトから個別にダウンロードできるCommand Line Tools for Xcodeをインストールしたのちに、以下の対応を行うと、プロンプトにgitの状態が表示される。
.bashrcに以下を記述する。
# Git
if [ -f /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash ]; then
source /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash
fi
if [ -f /Library/Developer/CommandLineTools/usr/share/git-core/git-prompt.sh ]; then
source /Library/Developer/CommandLineTools/usr/share/git-core/git-prompt.sh
fi
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUPSTREAM=auto
PS1="\h:\W \u\$(__git_ps1)$ "
# End Of File
これで完了だ。
以前、組み込みWebブラウザの会社に勤めていた関係で、独自の機能の呼び出しにURLスキームを利用する方法はよ馴染みがある。iOSでも同様にCustom URL Schemeを利用してアプリケーションを呼び出すことができるが、この方法は、スキームが重複と、意図しない外部サービスから呼べるという問題がある。
そこで登場したのがUniversal Links。
ただ、Custom URL Schemeの知識は必要だと思うので、まずは説明する。
スキーム名は、重複を避けるため、ドメイン名を逆から並べる、バンドルIDから派生した文字列がオススメされている。例えば、バンドルIDがcom.example.editorのアプリケーションの一覧画面を表示するスキーム名は、com.example.editor.listという感じにする。
Custom URL Schemeは、Info.plistに定義するが、Xcodeの画面から設定する方法もある。
まずは、Info.plistでの設定箇所を説明する。
Xcodeの画面から設定する場合は、TARGETS > Info > URL Types のIdentifierに識別子をURL Schemesにスキーム名を設定する。
iOS9以降では、安全性の観点からLSApplicationQueriesSchemesを設定するなどの対応が必要となる。
iOS9以降から利用可能。なので、それより前のバージョンをサポートする場合は、Custom URL Schemeの対応も必要。
対応手順は以下のとおり。
Webサーバのルートに、関連付けファイル (apple-app-site-association) を配置する。
{
"applinks": {
"apps": [],
"details": {
"チームID.com.example.アプリ名(バンドルID)": {
"paths":[ "*" ]
}
}
}
}
ファイル名は apple-app-site-association。
Content-Typeは application/json。
Appleの資料では、署名がある場合のContent-Typeは、application/pkcs7-mimeという説明があるが、Webサーバとの通信はHTTPSが推奨されているので署名されてなくても、なので、訳あってHTTPの場合の対応のようだ。
ちなみに、署名する場合は、以下の感じのコマンドとなる。
$ openssl smime \
-sign \
-nodetach \
-in "unsigned.json" \
-out "apple-app-site-association" \
-outform DER \
-inkey "private-key.pem" \
-signer "certificate.pem"
アプリケーション側の設定は以下のとおり。
XcodeのTARGETS > Capabilities > Associated Domains をONにして、Domainsにサーバのドメイン名を設定する。
これで、App ConnectのAppIDsが、この内容で更新されるはずだが、されていなかったら手動で変更する。
Universal Linksには、Universal Linksの設定が正しいかどうかを確認するサイトが用意されている。
Universal Linksからの呼び出しは、UIApplicationDelegateの、以下のメソッドで検出できる。
optional func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool