投稿

センター試験英語 2017

今年は172点。
時間はぎりぎり。もう少し読解スピードが上がると確認に時間を取れるようになる。
前半を間違えるのはいいけど、後半の間違いはくやしい感じ。

Xcode 8.2はシミュレータでスクリーンショットを撮ると落ちる on El Capitan

Xcode 8.2は、シミュレータに付いているスクリーンショット撮影機能(File->Save Screen Shot)を使うと落ちます。厳密に言うと1回目はOKで2回目に落ちる。

対策は
シミュレータで、Edit->Copy Screen
Previewで、File->New from Clipboard
手間もそんなに変わりません。

stackoverflowの記事(英語)

libswiftCore.dylibをロード出来ない問題

証明書はXcodeで自動で作成するようになったので、キーチェーンアクセスからappleの名前のものを手当たり次第削除して、Xcodeで一から作成したところ、アプリがシミュレータでは動作出来るのに、実機で実行できない問題にあたりました。Xcode 8.1です。
dyld: Library not loaded: @rpath/libswiftCore.dylib
というエラーが出ます。

ググったらキャッシュをクリーンさせる系の解決策もありましたが状況は変わらず。
最終的に
http://developer.apple.com/certificationauthority/AppleWWDRCA.cer
をダウンロードすることで解決しました。(プロジェクトのクリーンもやったかも)
https://forums.developer.apple.com/thread/21292
に書かれています。
このAppleWWDRCA.cerが何をするものかはわかりません。

No Common Blocks - Xcode 8から起こりがちなリンクエラー

Build SettingにあるNo Common BlocksというものがXcode 8からデフォルトでOnの模様。古いプロジェクトを初めてXcode 8で開くときに出てくる、コンパイラ設定変更の警告に従うとOnにされる。

これがOnだとObjective-Cのプロジェクトで、例えば
あるヘッダーでグローバル変数を定義している(例 : int a; )そのヘッダーが2箇所以上から#importされる の条件でリンクエラーを起こします。
externで回避しました。

ヘッダー側はextern int a;実装側でint a;
externの説明は他を参照して下さい。

検索用
Xcode 8
No Common Blocks
Apple Mach-O Linker Error
Linker command failed with exit code 1 (use -v to see invocation)
Message from debugger: Terminated due to signal 15

Swift 3.0でStringはどうなったか

前回Swift2.0のStringの仕様を調べたが、編集系(append, insert, remove, replace)のメソッドの仕様は整理しきれていない、というくやしい終わり方をした。
Swift 2.0でStringはどうなったか - 特殊文字などの扱い

今回はまず、この編集系メソッドから見ていく。
編集系メソッドの引数に与えるものは主にCharacterとStringであるが 、そのほかにCharacterを要素にもつシーケンスというものがある。これは、名前がSとして
<S : Sequence where S.Iterator.Element == Character>という性質を持つ。ここではこれを「Characterシーケンス」ということにする。

append(連結)系Swift2.0ではメソッド名がバラバラだったものが、めでたくappendに統一された。
CharacterやStringの場合は引数ラベルなしで与える。
Characterシーケンスの場合はラベルにcontentOfが付けられる。
mutating func append(_ c: Character)mutating func append(_ other: String)mutating func append<S : Sequence where S.Iterator.Element == Character>(contentsOf newElements: S)
このほかに土台のStringに変更を加えないで、与えられたものを追加したStringを返すメソッドがある。
func appending(_ aString: String) -> Stringこれは土台のStringが変更されないので、mutatingが付けられていない。他の編集系メソッドにも語尾がingでこの性質のメソッドがある。

insert(挿入)系これも名前がinsertに統一された。
appendと同じようにCharacterシーケンスの場合はラベルにcontentOfが付けられる。
Stringを受けるものはない?
mutating func insert(_ newElement: Character, at i: String.Index)mutating func insert…

Swift2.2からSwift3.0への変換を行ってみて

イメージ
Xcode8のGMが出たので、Swiftを2.2から3.0へ変換しました。自動でコンバートするXcodeの機能を使いました。
変換箇所があらかじめ表示されるので、一通り見て気が付いたことを書いていこうと思います。

enumの要素の頭文字が小文字に統一
どっちが正解なのかなぁと思いながらプログラムを作成していた部分なのではっきり決めてくれて良かったです。

配列の初期化メソッド
配列の初期化によく使われる
init(count: repeatedValue: )が
init(repeating: count: )
になりました。順番が変わって、さらに現在分詞になりました。

NS抜け
NSBundle が Bundle へ変更
NSIndexPath が IndexPath へ変更
NSURL が URL へ変更
Appleに従うのみ。

タイプメソッド扱いしていたものがタイププロパティ扱いに
NSBundle.mainBundle() が Bundle.main へ変更
UIScreen.mainScreen() が UIScreen.main へ変更
UIDevice.currentDevice() が UIDevice.current へ変更
UIColor.whiteColor() が UIColor.white へ変更
//例 open class var white: UIColor { get }従うのみ。

CoreGraphics衣替え
CGRectMakeなどのC言語ベースのCG***関数がSwift3.0では廃止になっています。
(旧)CGRectMake(***) が
(新)CGRect(***) へ変更、CGRect(***)の方はSwiftの構造体のinit命令呼び出しです。

(旧)CGPointMake(***) が
(新)CGPoint(***) へ変更、CGPoint(***)の方はSwiftの構造体のinit命令呼び出しです。

(旧)CGRectContainsPoint(CGRect rect, CGPoint point) が
(新)CGRectインスタンスに対するcontains(_:)メソッドへ変更

(旧)CGContextFillPath(CGContextRef cg_nullable c) が
(新)CGContextインスタンスのfil…

iOS10対策

イメージ
Privacy - Media Library Usage Description
この問題はシミュレータ(Xcode8.0)で発生したが、実機では発生しませんでした。
iPodライブラリの曲をアプリ内で使うとき、ユーザーに許可を取るようになりました。
この時の文面をinfo.plistに設定する必要があります。
Privacy - Media Library Usage Description(rawキーではNSAppleMusicUsageDescription)に何か文を追加します。
これを設定しておくと、アプリがライブラリにアクセスしようとしたところで、Don't allow / OKダイアログをOSが勝手に出してくれて、その中に先ほどの自分で追加した文が表示されます。
これを設定しないと、アプリが落ちます。
出す文章を各言語毎に変えたい時は、InfoPlist.stringsのローカライズをするとよいでしょう。

xibファイルのBuilds for
この問題はシミュレータ(Xcode8.0)で発生したが、実機では発生しませんでした。
[UIDeviceRGBColor length]で実行時エラーが発生しました。これは自分で書いたプログラムではないので原因がわかりにくかったのですが、xibファイルのBuilds forが未設定でした。Xcode3の時に作成したプロジェクトで発生しました。xibファイルのBuilds forをDeployment Target (8.0)にしました。

Swift2 標準ガイドブック

説明は全体的にざっくりアバウトな感じなので荻原本などを併用すること。

イニシャライザの項目に間違いが多いので修正があるといいです。

詳解Swift改訂版買いました

詳解Swift改訂版を買いました。Objective-C版も持っています。Objective-C版に比べて推敲が甘いかなと感じる部分が特に最後の方で多かったです。版を重ねて修正が加わるといいです。以下、自分用のメモ。構造体イニシャライザ内でメソッドを呼ぶのは初期値設定が全部済んでから。
構造体の内部で別の構造体を定義出来る。
構造体の内部で、typeエイリアスを使って、別名を与えることが出来る。(メリット?)
タイププロパティの値を変更するインスタンスメソッドにはmutatingは不要。
タイププロパティの初期化のための式は値が必要とされた時に初めて評価される。
didSet WillSetはinit()内での設定では呼ばれ無い。didSetで値を設定しても再帰的に呼ばれることはない。
オプショナルオプショナル==nilはnilかどうか
オプショナル==非オプショナルは中身を比べることが出来る
if letのほかにif varもある
readLineは標準入力
??の右はオプショナルでもいい。??は連鎖できる。配列配列を反対にするreverse()というメソッドがある。StringCharacterの配列からStringインスタンスを作るinitメソッドがある
UnicodeScalarにはvalueプロパティがあって値を取り出せる辞書新規はdict[a] = aaa
削除はdict[b] = nil
updateは更新、ただしもとからない場合は作成しない。Tuplelet aTuple = (1, 2, 3)
let (a, b, c) = aTuple //これが出来る
let (aa, _, _) = aTuple //使わないときは_が使える
値が一つだけのTupleはその値だけと変わらない
要素が一つもないことを()で表現。Voidは()の別名
違うキーワードのTuple間の代入は無理。型が同じでも。一度キーワードなしにキャストすればOK
キーワード付きのタプルの代入では順番が違っていてもキーワード毎に要素が代入される。キーワードがない部分は順番通りに代入される。
タプルにTypealiasでなまえをつけることができる。
Switchオプショナル付きのタプルを扱える
switch a { case (0, b?): break }のように使う。Enum…

xibでUIView内レイアウト設計してアプリに取り込むシンプルな方法 Swift編

イメージ
1.UIViewのサブクラスのソースファイルを作成。

2.UIViewをベースにして新規xib作成(UIViewControllerではない)。

3.xibで、UIViewのクラスを1で作ったクラスに設定する。


4.作成したUIViewを取り込みたいUIViewControllerなどでインスタンスを作成する
let settingView: SettingView = NSBundle.mainBundle().loadNibNamed("SettingView", owner: nil, options: [:]).first as! SettingView
5.xib内でレイアウトを行う。

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…