2017年9月21日木曜日

iOS11で不具合/ツイートできない

あくまでもiOS11にしたらアプリがうまく動かなくなったってことね。

ツイッターに投稿しようとしたら、

if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeTwitter) { }
がfalseになっちまいまして…orz
むろん今まではうまくいってた。

iOS11になった際に、自作アプリへのツイッターアクセスの設定がリセットされたのかしら?

調べたら、iOS11でいきなり非推奨どころか使用不可になってるみたい! ギョギャギャギャギャギャギャ!
どうやら、他社のサービスは他社のやり方でやれ、Appleはしらんわ…ということらしい。まあセキュリティの問題とかいろいろあるせいとは思うけど、めんどくさくなるのは勘弁してほしい。
ツイッター公式のTwitter kitというSDKがあって、今後はそっちを使わねばいけなくなるようだ。

詳しくは上のサイトのやり方に従って欲しいが、
  1. ツイッターにサインインしてアプリ情報などを入力
  2. Twitter Kit SDKをダウンロードしてXcodeのプロジェクトにインストール
  3. Xcodeのプロジェクトに必要なFrameworkを追加し、設定を追加
  4. ソースコードを編集
という手順になるようだ。
めんどくさいけど、百歩譲って、今までのiOSのTwitterの投稿ダイアログみたいなちっちゃくて使いにくいものから解放されるんならいいな。

今日は寝るので、また明日やってみた結果を追記する。

2017年9月20日水曜日

Swift 4リリース

Xcode 9でさっそくSwift 4がリリースされた。
2.x → 3 ほどの大きな変更はないと思うが、気付いた点があったら追記していく。

@objc推論の廃止

Dependency Analysis Warning
The use of Swift 3 @objc inference in Swift 4 mode is deprecated. Please address deprecated @objc inference warnings, test your code with “Use of deprecated Swift 3 @objc inference” logging enabled, and then disable inference by changing the "Swift 3 @objc Inference" build setting to "Default" for the "アプリ名" target. 
Swift 4モードでのSwift 3 @objc推論の使用は廃止されました。
推奨されない@objcの推論のWarningに対処し、「廃止されたSwift 3 @objc推論の使用」ロギングを有効にしてコードをテストし、 「アプリ名」 targetの 「Swift 3 @objc Inference」ビルド設定を 「Default」にしてください。

——Swift 3で作ったコードを開いたら出た。よくわからんのだけど、Objective-CのクラスとかをSwiftで扱う時に型を推定してくれてたのかな? んで、それが廃止になって、型変換とかを自分で明示的にやれ…とかそんな意味か?
別にObjective-Cのコードとか使ってなかったけど、Xcode 8でデフォルトでそういう設定だったんだろう。それなら自動で直してくれりゃいいのに。グチグチ。
ここをDefaultに変えるとWarningが消える
Build Setting、TARGETSにはアプリ名とアプリ名+Testsの二つがあるが、その両方にSwift 3  @objc inferenceの設定があるので、両方変えてやる必要がある。

#selectorの書き方?

Timer.scheduledTimer(timeInterval: 0.5,
                  target: self,
                selector: #selector(IdleEvents.filterUpdate(timer:)),
                userInfo: nil,
                 repeats: true)

こういうコードをSwift 3で書いてたんだけど、#selectorのところに以下のエラーが。
2番目のエラーにはFixってボタンが出るんでそれを押すと消えるんだけど、一時的なものらしく、また出たり、@objcってのをコード中の変なところに挿入されたり、なんだかよくわからん!
Argument of '#selector' refers to instance method 'filterUpdate(timer:)' that is not exposed to Objective-C
Add '@objc' to expose this instance method to Objective-C

どうやら、#selectorで呼び出す関数、メソッドの頭に「@objc」ということらしい。
@objc func hogehoge() { … }

んで、そんなこんなやってたら自作のクラスにExpected declarationというエラーが出るようになった。
調べたらコードの最後に「@objc」が付けられてた。さっきのFixボタンがいい加減なところに挿入しやがったんだな。

Xcode 9の変更点

2017/9/20にアップデートされたXcode 9について、Mac AppStoreの説明文の訳。

Xcode 9には、iOS11、watchOS 4、macOS High Sierra 10.13用のSwift 4とSDKが含まれています。
  • リファクタリングにより、Swift、Objective-C、C、およびC ++コードの構造を簡単に変更できます。
  • コードエディタは驚くほど速く応答性があり、Markdown構文のネイティブサポートを追加します。
  • Fix-itsはワンクリックでコードを複数改善し、必要なプロトコルメソッドを追加することもできます。
  • 新しいソースコントロールナビゲータと統合されたGitHubアカウントにより、チーム全体のコードを簡単に管理できます。
  • ネットワーク上のデバイス上のiOSおよびtvOSアプリケーションのワイヤレスインストールとデバッグ。
  • シミュレータは実際のデバイスのように見え、動作し、一度に複数のデバイスをシミュレートできます。
  • iOSのPlaygroundテンプレートは、XcodeとiPadのSwift Playgroundの両方で動作するドキュメントを作成します。
  • Find navigatorは非常に高速で、結果はすぐに表示されます。
  • プロジェクトナビゲータは自動的にファイルとグループをFinderとソースコントロールと同期させます。
  • XcodeサーバーはもはやmacOSサーバーを必要とせず、Xcode環境設定で完全に設定することができます。
  • 次世代のビルドシステムは、多くのプロジェクトを構築するとき(オプションで有効)、信頼性とパフォーマンスを向上させます。
  • Swift 4コンパイラは、Swift 3コードを構築して、一度に1つのモジュールで段階的な移行を可能にします。
  • 最新のSDKには、機械学習のためのCore ML frameworkと、拡張現実のためのARKitが含まれています。
えーと、Swift 4がもうリリースされたのだね Σ(((°Д°;))))ガクガク

2017年9月19日火曜日

URLスキーム/URLで地図アプリを開く

やりたいこと

緯度経度の位置情報を持ったリンク(たとえばTwitterのツイートとか)を押すと、自動的に地図アプリを起動して指定した場所を表示してくれるようにしたい。

こういうのをURLスキームという。

2種類のスキーム

Appleのマップ用

iOSの場合のURLスキームは以下のものとなる。
http://maps.apple.com/maps?パラメータ

これはApple純正マップ.appがインストールされているデバイスではマップ.appが優先的に起動し、非インストール機(WindowsやAndroid含む)ではGoogleMapが起動される(GoogleMapアプリがなければブラウザ上で)。

GoogleMaps専用

詳しくは公式ガイドページ
マップ.appがインストールされたデバイスでもGoogleMapを起動することもできる。
https://maps.google.com/?パラメータ
https://www.google.com/maps/preview/パラメータ

こちらはMacなら直接ブラウザで、iOSのTwitterアプリならそれの子プロセスとしてWebビューが開く。
iOSの場合、右上のアイコンからSafariで開き、さらにSafariで開いた画面上部に"Google Maps" Appで開くという表示から、GoogleMapsアプリで開くこともできる(アプリがインストールされていればだが)。
試してないがWindowsでもAndroidでも同じような感じだろう。
GoogleMapsアプリで開くまでが少し手間だが、難しいことではないし、たいていは子プロセスとしてのWebビューで事足りるだろう。

comgooglemaps://?パラメータ
などという方法もあるが、こちらは直接ブラウザを経由せずにGoogleMapアプリを開くためのもので、ツイートに直接書き込んでもURLとして認識されない。
ブラウザのURL欄に書いた場合、iOSでは直接GoogleMapsアプリが開けたが、アプリがないMacだと当然ダメ。素直にhttps〜形式の方がいい。

どっちの方がいいか

機能としてはGoogleMapsの方がStreetViewがあったりと高機能なので、当面は後者のURLスキームの方が良さそうだ。
同じ緯度経度、表示範囲(拡大率)を維持したまま相互を切り替えられるといいんだけどな。

2017年9月17日日曜日

Objective-CのコードをSwiftに移植

Swift3にもなって、そろそろObjective-Cで作ったアプリをSwift化した方がいいと思うようになった。

メンテナンスのたびにObjective-Cを思い出しながら作業するのも面倒。
いつアップルが「もうObjective-Cのサポートやめるから、これからは審査通さんからね」って言い出しかねない。
なんだかんだ言ってObjective-Cのコードはごちゃごちゃしてることが多い。ヘッダファイルやimportも必要だし。

そんなわけで今さらだが、Swiftに移植してみることにした。

以下、調べたことのメモ

  • 同じプロジェクト内でクラスのファイル(ViewController.h、同.mとか)ごとに移行可能。
  • クラスのファイル名は拡張子が別になるので、Objective-CとSwiftで同居可能。(ViewController.h、同.m、同.swift)
  • 最初にSwiftファイルを追加するときに「bridginf header」というファイルを作るかどうか聞かれるので、作っておく。

手順

移行するクラスファイルと同名のSwiftファイルを作ってコードを移植。
Objective-Cの.hと.mのファイルを削除。
Storyboardに結びついてるならCustom ClassのModuleがNoneになってるので、そこをプロジェクト名に直す。(最初にCurrentに直すとも?)
IBOutletやIBActionの結びつきを直す。

Objective-C、Swift相互の呼び出し

Objective-CのクラスからSwiftのクラスを呼ぶには、呼び出し元のObjective-Cのファイルに
#import "アプリ名-Swift.h"
を追加。
逆にSwiftからObjective-Cを呼ぶには作っておいた「プロジェクト名-Bridging-Header.h」に呼び出し先のObjective-Cファイルをimportする。

でいいらしい。

AppDelegateの移植

AppDelegateも同様に移植する。
Objective-CではSupportingFilesフォルダ中にmain.mが作られてるけど、これが残ってるとかえってエラーになるので、削除する。
Swiftの普通のAppDelegateを参考にすりゃわかるけど、class AppDelegateの前に@UIApplicationMainってのを書いてやる。
多分これで最初に呼ばれるファイルに指定されるんだろう。

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

2017年9月14日木曜日

TableViewを使う


Xcode右下の部品一覧からUITableViewControllerをStoryboardにドロップすると簡単なんだけど、なぜかTableViewにConstraintsが設定できない。
一番上のCellがステータスバーに重なってしまうなどよろしくない。

普通のUIViewControllerにUITableViewをドロップし、UIViewの子Viewにすればこれは回避できる。
その際はTableViewとViewControllerをdelegateとdataSourceで結んでやること。(Storyboardの黄色いアイコンまで右ボタンドラッグ)

TableViewのStoryboard IDとか、TableViewCellのRestoration IDとかも設定した方がいい。

また、ViewControllerに結びつけるSwiftのクラスはUIViewControllerを親クラスとし、UITableViewDelegateと同DataSourceを設定してやる。

class TableViewController: UIViewController, UITableViewDelegate,UITableViewDataSource {
}

さらに、delegateメソッドはoverrideにしない。

2017年9月12日火曜日

乱数の関数メモ

いろいろある乱数発生の関数をメモ

arc4random()
返り値の型はUInt32なので、Swiftみたいに型をきっちり指定してやらないといけない言語の場合、ちょい面倒。

arc4random_uniform(__upper_bound: UInt32)
0〜引数-1までのランダムな整数を返す。
arc4random_uniform(10)なら0〜9まで。使い勝手良さげ。


drand48()
返り値の型はDoubleらしい。
0.0〜1.0の間の負でない倍精度の浮動小数点値を返す。
UIColorのrgb値が0.0〜1.0とこれにドンピシャガンガンなので、いちいちarc4randomとか使わんでいい。
今知ったばかりなんでよくわかってないw