投稿

2015の投稿を表示しています

Swift Compiler Architecture (Swiftコンパイラの構造)

Swiftがオープンソースになって公開された資料の中でSwiftのコンパイラについて書かれている部分を抜粋し、日本語に訳す。意味がわからないところは(?)を付けた。

Compiler and Standard LibraryThe main Swift repositoryにはSwiftのコンパイラとスタンダードライブラリのソースコードがあります。

Compiler ArchitectureSwiftで書かれたソースコードからLLVM IRに変換される工程です。上から下に流れていきます。
Parsing (lib/Parse) : parserはソースコードをAbstract Syntax Tree (AST)に変換します。ここでは意味の情報も、型の情報も扱いません。ソースに文法の問題があるときはメッセージを出します。Semantic analysis (lib/Sema) : parseされたASTを整形された型チェック済みのASTに変換します。意味の問題があるときはメッセージを出します。ここには型推論が含まれます。Clang importer (lib/ClangImporter) : Clang modulesをインポートします。そしてCやObjective-CのAPIと対応するSwiftのAPIをmapします(?)SIL generation (lib/SILGen) : Swift Intermediate Language (SIL)とはSwift用の中間言語で、さらなる分析と最適化に適しています。SIL generationは型チェック済みのASTを"生の"SILに"レベル下げ"します。SIL guaranteed transformations (lib/SILOptimizer/Mandatory : 変数の初期化などのデータの流れを診断します。この工程を終えると“canonical(正式な)” SILとなります。SIL Optimizations (lib/SILOptimizer/Analysislib/SILOptimizer/ARClib/SILOptimizer/LoopTransformslib/SILOptimizer/Transforms) : ARCなどの最適化を行います。devirtua…

Objective-Cで保存したアーカイブデータをSwiftで読み込む

アプリをObjective-CからSwiftに書き換える際、少し悩むことに、Objective-Cで保存したアーカイブデータ(ユーザーのデバイスに保存されている)をSwiftで読み込むにはどうすればいいのかということがあります。
ここでは、NSKeyedUnarchiverやNSKeyedArchiverクラスを用いて利用するアーカイブデータがデバイスに保存されている場合に限定して、アプリをSwiftに書き換える時の手順などをまとめます。


ファイルの場所の指定
データの保存と読み込みではファイルの場所を指定します。ファイルの場所の指定はObjective-CとSwiftでほとんど同じ感覚でいけます。
var fileName = "" let paths: [String] = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) if 0 < paths.count { fileName = paths[0] fileName.appendContentsOf("/targetObject.dat") //print(fileName) } if 0 < paths.countは一応入れといた。
ちなみにstringByAppendingPathComponentというNSStringクラスのメソッドは使えなくなったようです。追加するものの前に自動的に/を加えるメソッドです。URLクラスに同じ機能のメソッドがありそっちを使えと表示が出ます。使えなくなったのが意図的だとすればStringとして扱うかURLとして扱うか中途半端ということでしょうか。


アプリにアーカイブ機能を付けるためにソースを書く部分
主に3つあります。
1 : データを保存するところ
2 : データを読み込むところ
3 : データ自体の定義


データの保存/読み込み
データの保存/読み込みの仕方は
A : オブジェクトをファイルに直接アーカイブする
B : NSDataを介してオブジェクトをファイルにアーカイブする
と2つあります。保存時と読み込み時でやり方が「対」になっていると余計な問題が出ることを避けられると思います。Obje…

Swiftのオプショナルのオプショナルて何??

イメージ
オプショナルのオプショナルはあります。
正式な呼び方がなんなのかはわからないけど確かにあります。ちょっと長くなるけど調べたときのいきさつ形式で書きます。

エラーハンドリングについて調べていたときに以下のコンパイルエラーに遭遇しました。

Value of optional type 'Int?' not unwrapped; did you mean to use 'try!' or chain with '?'?
オプショナルの値のInt?はアンラップされません、やろうとしていることはtry!か、?を使った連鎖で出来ませんか?

このエラーは以下のようなプログラムの最後にある try? で出ました。実行はPlaygroundです。
enum MyError: ErrorType { case myError } func someThrowingFunction(a: Int) throws -> Int { if 1 < a { throw MyError.myError } return a } func someFunction() { let a: Int = try? someThrowingFunction(5) //ここでエラー発生 }このエラーメッセージは、「try? というのは戻り値を格納する値の型をオプショナル型にする必要があるのでして下さい」という趣旨のメッセージです。ここでは最後のaの宣言を Int? にすればよいです(または型を書かずにコンパイラに推論させればよい)。
まあこれでこの件は解決なんですが、ただ、メッセージの最後の chain with '?' (?を使った連鎖)が気になりました。chainは連ねるという意味ですから??のように重ねること?なぜこの状況でchainが出てくるのか?といろいろ考えているうちに、もしかして ?? というものがあるのでは?と思い、以下のプログラムを試してみました。メソッドの戻り値を Int? にしてみました。
//戻りをInt?に変更 func someThrowingFunctionOPT(a: Int) throws -> Int? { if 1 < a { throw M…

従来のソフトのままでiPad Proの画面に対応する方法

イメージ
以下の記事はちょっとまだ公式のソースを確認できていないので自己責任でお願いします。

iPhoneが3.5インチサイズから4.0インチサイズに移行したときは4.0用の起動画面を用意することで4.0に対応していることを示すやり方でした。用意しなければ真ん中に3.5インチサイズの画面が出て、黒い帯で上下の空いた領域を埋める仕様でした。iPhone6や6sのときも対応/非対応の区別は起動画面を用意するかしないかでした。

今回iPad Proが新規解像度2732 x 2048で出てきましたが、対応/非対応のポイントはやはり起動画面のようです。
ただ今回はファイルを用意するのではなく、Launch Screen File(storyboard風のやつ)が設定してあることが「iPad Proに対応している(2732 x 2048も想定して描画処理を書いてある)」ことを示すようです。図のSourceのほうではなくてFileのほうです。iPad Pro対応しないとき(iPadのレギュラーサイズの画面を引き伸ばしたいとき)は「なにも設定しない」にしてください。こうすることで内部でiPadレギュラーサイズとして描画したものをiPad Proの画面の大きさに引き延ばすような処理になります。
ちょっとまだ公式のソースを確認できていないので自己責任でお願いします。実機はまだ発売されていないので確認したのはシミュレータのみです。Xcodeは7.1です。

未来ぽい感じがして好きだったんですが一旦OFFにしておきますかね。

Swift 2.0でStringはどうなったか - 特殊文字などの扱い

イメージ
Objective-CのNSStringの仕様は自然ではなかったので、Swiftには期待しています。
Swift2.0でStringの仕様がだいぶ変わったということで検証してみます。

昔は何が困ったか今回のStringの仕様の検証は、昔の仕様で困っていた部分が動機になっているので、まずそれを書きます。NSStringでは文字を基本的に16ビットで扱っていますが、文字の中には16ビットで扱えないものがあり、そういうものは32ビットなど他の長さで使用します。そのごちゃごちゃはUnicodeの仕様上仕方ないのですが、NSStringではその32ビット文字を2文字としてカウントするなどUnicodeのごちゃごちゃをうまくさばききれていなくて扱いが雑な部分がありました。
欲しいものは、内部で何ビットだろうとどういうどういうデータ状態であろうと、人間が一文字と認識するものは一文字として扱うというポリシーに従ったAPIです。
Swiftが発表になったときにUnicodeとの親和性もアピールしていたので期待しています。


The Swift Programming Languageを読むまずはいつものThe Swift Programming Languageで基本をおさらい。
・Stringはvalue typeである(reference typeではない)。
・Stringの文字列に含まれている個々の文字へのアクセスにはStringのcharactersプロパティからアクセス出来る。
・SwiftのStringは内部ではUnicode scalarをベースにしている。Unicode scalarとは文字や記号に対応する21ビットの数。U+0000からU+D7FFとU+E000からU+10FFFFがある。U+D800からU+DFFFは含まない。U+が何かというのは大変ややこしいので割愛。
・人間が文字と認識する形式がExtended Grapheme Cluster。SwiftのCharacterは一つのExtended Grapheme Clusterに対応。一つのExtended Grapheme Clusterは一つ以上のUnicode scalarで構成される。
・Stringの文字数カウントはcharactersプロパティのcountプロパティで取得出来る。取得されるのはC…

Swiftブログの要点まとめ 2015

イメージ
appleの公式Swiftブログ(英文)
の各記事の要点を日本語でまとめます。
英語のトレーニングを兼ねて...


Swift is Open Source
2015年12月3日
Swiftはオープンソースになりました。
関連項目は
Swift.org Swiftに関わる人のためのサイトgithub.com/apple ソースコードの置き場Swiftパッケージマネージャーというコードを共有したりビルドするためのツールSwiftネイティブコアライブラリというスタンダードライブラリの上のレベルのものLinuxだけでなくAppleのプラットフォームにも対応

Literals in Playgrounds
2015年10月7日
Playgroundでファイル、色、画像の扱いが可能になりました。


Swift 2 Apps in the App Store
2015年9月21日
Swift 2で作成したアプリが提出可能になりました。
Xcode 7はSwift 2を含みます。Swift 1.2から変更するにはEdit > Convert > To Latest Swift Syntaxを使用して下さい。
OS X El CapitanでXcodeを使うならXcode7を要求します。Xcode 6を使い続けるならOS X Yosemiteのままにして下さい。Xcode 7とYosemiteの組み合わせはOK。


Swift-er SDK
2015年8月12日
Xcode 6.3でObjective-Cに新しい機能のnullability annotationsが付きました。SwiftのOptionalに相当します。


Strings in Swift 2
2015年7月23日
Swift 2ではStringの仕様が変わります。
今までStringはCharacterのコレクションとして扱ってきましたがSwift 2ではそうではありません。Swift 2ではStringはcharactersというプロパティを持ち、そのcharactersプロパティがコレクション(文字の集まり)の性質を請け負います。
変更の理由は、StringはArrayやSet,Dictionaryといったコレクションとは極めて異なる振る舞いをしなければならないことです。このStringの性質はもとからなのですが、S…

Xcode7の時点でCertificate(証明書)とProvisioning Profileの作成は(ほぼ?)全自動に

イメージ
Certificate(証明書)とProvisioning Profileを全部削除した状態で、Xcode7でデバッグ(手元デバイスでの動作チェック)とストアへの申請を行い、どの程度自動作成機能が使える状態になっているか確認する。頻繁にチェックしているわけではないので実はXcode6のときにすでに出来ていたと言われる可能性もあるが、とりあえずやってみる。

1、developer.apple.comのCertificates,Identifiers & ProfilesページでCertificateとProvisioning Profileを全部削除する。App IDとDeviceは使用するものが設定してある。App IDはそれぞれのアプリ個別のもののみがある。


2、Xcode7の環境設定の中のAccountsのView Details...ボタンをクリック。出てきた一覧表に上下2つのエリアがありますが、上のSigning IdentitiesはCertificateに対応しているようです。Provisioning Profileがあれば(ローカル環境に残ったもの?)削除する。Signing IdentitiesのiOS DevelopmentとiOS DistributionにはCreateボタンがあるが作成はせずにスルー。



3、Xcode7でプロジェクトを開く。Bundle Identifierは設定してある。当然、No provisioning profiles foundの黄色警告が出る(ターゲット設定のGeneralタブのIdentitiy)。修正するためのFix Issueボタンも表示される。この時点でシミュレータでは実行可能。

実デバイスで実行しようとするとNo Provisioning profiles foundの赤色アラームが発生。実デバイスでの実行は不可。


4、ここでお待ちかねのターゲット設定のGeneralタブのIdentitiyのFix Issueボタンを押す(裏で何をやっているかわからないから好きではないという意見もあるかも)。するとiOS DevelopmentのCertificateが作成され(Createボタンが消える)、App IDにもXcode iOS Wildcard App IDというものが作成された。そしてそれらを…

iOS9対応でやったこと

[NSLocale preferredLanguages]
[NSLocale preferredLanguages]で返ってくる言語設定が
iOS8まで ja
iOS9から ja-US
のようになったので対応。
isEqualToString:@"ja"
から
hasPrefix:@"ja"
へ変更すればOKと思いましたが
ジャマイカ...
が脳裏をよぎり
isEqualToString:@"ja"とhasPrefix:@"ja-"のORにしておきました。


NSManagedObjectContext
[[NSManagedObjectContext alloc] init]が9.0でdeprecatedになったので
[[NSManagedObjectContext alloc] initWithConcurrencyType:]
に変更しようと思ったがConcurrencyTypeの設定が難しすぎて一旦保留。


Requires full screen
iPadアプリで「全方向対応でない場合はRequires full screenをONにするように」というワーニングが出たのでONにする(そのアプリは縦のみ対応)。
このパラメータはSlide OverやSplit Viewで画面の一部の表示をされたくない時にもONにするものらしい。

(追記 : 以下のバグはXcode7.1.1では修正されていました)
ちなみにiOS9.0 Xcode7.0の段階でSlide OverやSplit Viewを有効にするとなぞのバグ(?)があって、
フルスクリーン状態で(Slide OverやSplit View状態ではない)デバイスを回転させて、UIDeviceOrientationDidChangeNotificationを受けた時に
self.view.bounds.size.width
self.view.bounds.size.height
が変更前の状態で取得されてしまって使えなくなるという現象があった。その値を元に全体の要素を配置しているので、縦にすると横の配置になり、横にすると縦の配置になるという現象。
[[UIApplication sharedApplication] statusBarO…

SwiftでのdrawRect()

UIViewのdrawRec()メソッド内で線を描いたり円を描いたりするやり方について。

CGContextなんとかという関数を用いる方法が広く紹介されているが、実はUIBezierPathというクラスもある。これはCGContextなんとかを機能的にラッパーしたクラス。Appleの資料によるとこちらの方がおすすめらしいのでこれを中心に紹介していく。Bezierというとややこしい数式を用いた描画というイメージがあって名前で少し敬遠してしまうが、線を引いたり丸を描いたりといった単純な描画でもこのクラスをメインにするといい。UIPathのようなシンプルな名前にしておけばもっと人気(?)が出たかもしれない。

描くときの大まかな流れは
1 線の太さや使用する色を指定
2 パス(線要素)を必要なだけ足していく。
3 描画指令を出す
となる。

UIBezierPathを使った描画
//色の設定
UIColor.redColor().setFill()
UIColor.blueColor().setStroke()
UIColorに色設定メソッドがあります。UIBezierPathというのはPathに関するものなので色は専門外なんでしょう。

でここからUIBezierPathのメソッドです。

//空インスタンス作成
let line = UIBezierPath()

//線の太さ
line.lineWidth = 2

//開始点
line.moveToPoint(CGPointMake(10, 10))

//追加点
line.addLineToPoint(CGPointMake(20,20))

//パスを描く
line.stroke()

//パスを閉じる
line.closePath()

//円や楕円
let daen = UIBezierPath(ovalInRect: CGRectMake(100, 100, 100, 100))

//四角
let shikaku = UIBezierPath(rect: CGRectMake(100, 100, 100, 100))

//中を塗る
daen.fill()
shikaku.fill()

//角が丸い四角
let kadomaruSHikaku = UIBezierPath(roundedRect: CGRectMake(100…

Swift資料の英単語 - Using Swift with Cocoa and Objective-C

実際に資料を読みながらわからなかった単語を記載していく。
英語は得意というわけではないので若干の誤りがあるかもしれない。
本文に合わせて多少変更した意味になっているところもある。
Using Swift with Cocoa and Objective-Cの範囲です。

Getting StartedInteroperability 相互に操作出来ること?
interface 連結する
take advantage of を利用する
Migration 移行
identical 一致する
delineation 記述?
reside 居住する
vend 販売する、(この文脈では)供給する
leverage 投資する、(この文脈では)導入する

InteroperabilityInteracting with Objective-C APIscome over やってくる
get sliced off 外される
respective それぞれの
consistency 一貫性
audit 検査する

Mix and Matchincorporate 取り入れる
coexist 同時に同じ場所に存在する co + exist
straightforward わかりやすい
depict 表現する

メモ
Bridging-Headerを使う。SwiftからアクセスしたいObjective-CのヘッダーファイルをBridging-Headerに書く。
Xcode-generated headerを使う。Objective-CからアクセスするSwiftのファイルが書かれる。

Migrationrevisit 再検討する
hassle やっかいごと

詳細!Swift iPhoneアプリ開発 入門ノート

表紙はiOSプログラミング本にはめずらしいオレンジ色。(初版)

6章以降は、アプリを作ったことがあるとちょうどいい内容です。サンプルはなかなかコアなところを選んである。
今までiOSアプリを作ったことがない人が、これで一からやろうとするときついと思う。今までにいくつかアプリを作った人でないと理解できないような表現がけっこうある。

XcodeのAssistant EditorのManualを、選べない状態から正常な状態にする

イメージ
Xcodeを使っていて困ることの一つにAssistant EditorのManualが正常に機能しないということがあります。どういうことかというと
通常は

このようにManualの下にProjectがあり、その下にある任意のファイルを選べるようになっています。

しかし、ときどき

このようになり、現在選ばれているものから変更出来ない状態になります。


ここから正常な状態に復帰させる(ことが出来るかもしれない)手順です。Xcode6.2 OSX10.9で確認しております。他の環境では出来ない可能性もあります。

1,まずManual以外のものを選択し表示を切り替えます。


2,一旦Assistant Editorを閉じます。


3,再びAssistant Editorを表示させます。


4,Manualが正常に戻る(かも)。


自分の環境では100%修正可能でしたが、どんな環境でも必ず正常に復帰できるかどうかはわかりません。参考になれば。

ちなみに、そもそも何故不安定な状態になるかですが、いろいろやってみたところ"Manual"自体をクリックしたときの制御が不安定のようです。Manualにして何かのファイルを表示したいときはマウスで目的のファイルまで辿り着いてからクリックするとこの不安定なポイントを避ける事が出来ます。

UIFontのfontName一覧 iOS8版

参考記事
Over&Out その後 UIFontのfontName一覧

これのiOS8版を行います。
""が付いているものと付いていないものがありますが、どちらも指定できます。
使用例
[UIFont fontWithName:@"Courier" size:512];
family:Marion ( "Marion-Italic", "Marion-Bold", "Marion-Regular" ) family:Copperplate ( "Copperplate-Light", Copperplate, "Copperplate-Bold" ) family:Heiti SC ( "STHeitiSC-Medium", "STHeitiSC-Light" ) family:Iowan Old Style ( "IowanOldStyle-Italic", "IowanOldStyle-Roman", "IowanOldStyle-BoldItalic", "IowanOldStyle-Bold" ) family:Courier New ( "CourierNewPS-BoldMT", "CourierNewPS-ItalicMT", CourierNewPSMT, "CourierNewPS-BoldItalicMT" ) family:Apple SD Gothic Neo ( "AppleSDGothicNeo-Bold", "AppleSDGothicNeo-Thin", "AppleSDGothicNeo-UltraLight", "AppleSDGothicNeo-Regular", &…

bridge系のキャスト

よく忘れてしまうので…


何がカウンタ方式か
ARC obj-cでも非ARC obj-cでもCF系(CoreFoundation系)でも全部カウンタ方式。プログラマが管理文を書くか書かない(コンパイラが書く?)かの違いはある。


カウンタはどこで持つか
2つの変数が同じインスタンスを参照している時カウンタはいくつか?
1つ。


__bridge系って何?
id系とCF系のキャストの箇所でコンパイラがretainとreleaseをどう書くかを指定するもの。
__bridge
__bridge_retained
__bridge_transfer
の3つ。
何をどう使ってもretainとreleaseがきちんと数を合わせて実行されてれば間違いではないと思いますが、3種類あるのは、人が見てわかりやすいとか、下で書くような管理責任をどうしたいのかを表すのには便利かと思います。


オーナーシップについて
オーナーシップという言葉で説明してあるものがかなりあります。もしよくわからない場合は、一旦retain releaseの追加という観点で理解してから、再度オーナーシップについて考えるのがおすすめです。


それぞれのパターンでキャストして代入するとこうなります。

__bridgeによるCF系からid系
id系 = (__bridge id系)CF系
id系がARC管理下に入ることによりカウンタ+1。ただし__weakであれば増加処理はなし。
キャスト後もCF系で管理したいときにおすすめ。id系が消えたあともCF系を使いたい時など。

__bridgeによるid系からCF系
CF系 = (__bridge CF系)id系
カウンタ変わらず
引き続きid系による(自動)管理をしたいときにおすすめ。キャスト後のCF系は管理しないことが前程だが一応管理命令は実行出来る。

__bridge_retainedによるid系からCF系
CF系 = (__bridge_retained CF系)id系
CF系がretainされるので+1
キャスト後のCF系で管理したいときにおすすめ。
id系は引き続き管理されている。

__bridge_transferによるCF系からid系
id系 = (__bridge_transfer id系)CF系
CF系がreleaseされることにより-1。キャスト後のCF系は管…

Interface「新時代コンパイラ入門」はよかった

Interface2015年3月号は「高性能でフリー!新時代コンパイラ入門」特集。
Swiftのコンパイルエラーの記事を書いたこともあって買ってみました。
変なハショリなどもなく読みやすかったです。
話に出てくるコンパイラはいさぎよくGCCとLLVMに絞ってあります。
コンパイルの各工程の解説が書かれています。

対象読者は普段プログラムをされている方か昔されていた方。そうでない方だと意味のわからないアルファベットが大量に出てくる状態になってつらいかもしれません。

対象とする前程知識はかなり基本的なコンパイラの知識で十分です。
・コンパイルとはプログラムを解釈してCPUへの命令に置き換える作業
・ARMとはCPUの設計をする会社
・ARMが作ったものにはv7やv8などがある
程度でOKでした。

自分が読んだ部分はSwiftでの開発に関係ありそうなところだけで
イントロダクション
Appendix 1
第1章〜第6章
でした。

Clangの機能の使い方についての説明があった。これはブログで記事を書くのに役に立ちそう。