ios

iOS11とXcode9について思ったこと

Xcode9でのAdHocアプリのエクスポートまわりが色々と変わっていた。 Xcode ServerがXcodeに同梱されるようになった影響かもしれない。 https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/TestingYouriOSApp/TestingYouriOSApp.html AdHocビルドするときに今まではTeamの選択をするだけだったけどプロビジョニングプロファイルも選択できるようになっていた。また成果物もAdHocビルドしたときに今まではipaファイルだけ書き出されてたけど Packaging.log ExportOptions.plist DistributionSummary.plist というファイルたちも書き出されるようになった。これによって書き出したアプリのバンドルIDや使用したプロビジョニングファイルなども確認できるようになった。 これで本格的にCIを使った開発環境の構築が進められそう。 Swift4系への以降はまだ自分が開発しているプロジェクトでは行えなさそうなので、様子見しつつかな。 UIViewController.topLayoutGuide/bottomLayoutGuide が

xcode8

Xcode8でBundle IDを設定する

Xcode8でBundle Identifier(以降Bundle ID)を設定する方法。 たしかXcode7あたりから設定箇所が変わりましたよね。 プロジェクトを作る Bundle IDはプロジェクトを作るときに設定する項目から自動的に作成されます。 <Bundle ID> = <Organization Identifier>.<Product Name> Bundle IDを変更する ただ単にBundle IDを変更する場合の手順 Project Navigator(左ペインの一番左のアイコン) プロジェクトの設定を開く Bundle IDを変更したいTARGETを開く Bundle Identifierを書き換える

ios

iOS開発初心者に知ってもらいたい開発スキル

この記事は画像がたくさんだったりしてすごく長いです。 SwiftでiOS開発の勉強をしている会社の新人と話をしているときに実装中のコードを見せてもらうと気になる実装があった。 let action = UIAlertAction(title: "title", style: .default, handler: { (action: UIAlertAction!) in ... }) UIAlertActionのイベントハンドラになるクロージャの引数の型が違う。 このイニシャライザのメソッド定義はこちら。 open class UIAlertAction : NSObject, NSCopying { public convenience init(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) ->

ios

iOSバージョンのシェアとアプリの対応OSバージョン@2016秋

iOSバージョンのシェアとアプリが対応するOSバージョンについて考える。 2016秋っていうのはざっくりとした期間にしたかっただけ。 Apple公式が出しているおおよその数値 2016年10月の時点でiOS8系とそれ以前のバージョンはAppStoreにアクセスしているうち8%ってことみたいですねー。だいぶ減りましたね。 私がかかわっているアプリではfabricをクラッシュレポートとしてとして使っていて、オマケ感覚でfabricのAnswersというDAUとか計測できるトラッキング機能を使用しているのですが。そのアプリだとiOS8系のユーザは3%弱でした。iOS8以降をサポートしているアプリなのでAppStoreとは分母も違うしってところですが、リテラシーが高い人向けというわけでもないアプリでiOS8系ユーザが3%弱ってことは、今後開発するアプリはもうiOS9以降サポートでいいよね!iOS8系は切り捨てちゃっていいよね! ここ数年で「古いOSもきっちりサポートしてよ」みたいな話は聞かなくなってきた気がします。 個人的にiOS8が切り捨てられて嬉しいこと 説明めんどくさいのでリンク先見たりググったりしてください。 Storybaordの分割 ( iOS8も対応したプロジェクトの場合にはこっち WKWebViewがiOS9でいろいろ強化された(UserAgentカスタマイズできるらしいプロパティ追加された UIStackView UITableView.readableContentGuide(使ったことないけどあると良さそうだなと思う 3D Touch(未だにまともに使ったことない What's New

xcode

iOS10.1 ATS

前回の検証がBeta版だったので安定版でも検証した 検証環境 iPad Pro 9.7 iOS10.1 Xcode 8.1 Swift3 検証方法 非SSLリクエスト先はhttp://www.example.com SSLリクエスト先はhttps://www.example.com 非SSLリクエストとSSLリクエストを行い結果を確認する(合計8つのリクエスト) UIWebView WKWebView NSURLSessionで該当URLのソースコードをダウンロードして表示 NSDataで該当URLのソースコードをダウンロードして表示 これらのリクエスト結果がATSの設定パターンでどのように変わるのかを比較する 検証手順 上記検証方法に対応したプロジェクトを作成して実機起動(シミュレータは実機と異なる動作をすることが多いため) http(s)

ios

iOS10ライフサイクル

先日Xcode8のフレームがどうのって記事を書いたんですけど、そんなことよりライフサイクルだな。と思ったのでシーケンス図風のものを書き出しました。png貼ってますがサイズ大きめです。参考程度に。上から下へ処理が進んで行きます(意味わかるよね? 今回使ったアプリ 確認した内容はこんな感じ + AppDelegate | | | + UINavigationController | | | +-+ UIViewController | | | +-+ UIView(UIViewController.view | + Notification Storyboard使って、画面遷移などはしていないです UITabBarControllerも使っていないです(ライフサイクルが結構かわるのですごく長くなるから 起動 その他バックグラウンド/フォアグラウンドなど その他 バックグラウンドに移行する ≠ フォアグラウンドではなくなる(アプリが見えなくなる) バックグラウンドに移行したかどうかは didEnterBackground でしか判断できない UIApplicationXXXなステータス変更のNotificationはAppDelegateのメソッドが呼ばれた後で最後に通知飛ばされてるみたい

xcode8

Xcode8 UIViewController.view.subviewsのframeについて(追記しました)

ビューのサイズが1000x1000になる Xcode8からStoryboardやxibでオブジェクトがframe値を持たなくなった影響で、UIViewController.view.subviewsのビューが正常なサイズを取得できなくて困るという話をよく耳にしている。 こんな感じのやつ <UIView: 0x7ff823d04e80; frame = (0 0; 1000 1000); autoresize = RM+BM; layer = <CALayer: 0x61000003dca0>> 自分もこれで困ることはあったけど、まぁ仕方ないからラクしないで修正しようか。くらいの気持ちでした。 検証した まずは通常のライフサイクルを確認する。 UIViewControllerとUIViewを拡張してログ出力するようにした。 // UIViewControllerのログ print("\(Date(

ios

UICollectionViewで横スクロールページングのインデックス取得

UICollectionViewでシンプルなページングする横スクロール画面を実装した時に、何番目のセルを表示中か取得しようとしたらうまくいかない状況があったのでほぼメモ。 // Before - (NSInteger)visibleIndex { NSInteger index = NSNotFound; NSArray<NSIndexPath *> *indexPaths = [self.collectionView indexPathsForVisibleItems]; NSIndexPath *indexPath = [indexPaths firstObject]; if (indexPath) { index = indexPath.row; } return index; } // After - (NSInteger)visibleIndex { NSInteger

ios

UniversalLinksを実装した

仕事でUniversal Linksを実装することになったので検証環境を用意した。検証に使用したドメインは www.ikenie3.org 。Universal Links単体の実装というよりはHandoffとUniversal Linksの設定を同時に行っていく流れになりました。雑なので他の人が見ても意味がわからないかもしれないレベルのメモです。 作業内容 1. サーバ: https化 まず http://www.ikenie3.org をhttps化した。 が、必須ではなかったらしい。 URLがhttpsに対応している、もしくはUniversal Linksで使用するJSONファイルが署名されていることが条件ということでした。 証明書に関してはHandoffProgrammingGuideに指定の記載があります。 その際、iOSが信頼する認証局 (http://support.apple.com/kb/

ios

Swiftでアプリのバージョンチェック

アプリのバージョンチェックを実装するときは、特に何も考えず String.compare: メソッドを使えばいいじゃんと思っていたのですが、 String.compare: だけだと問題がありました。 結論 こんな感じで、 compare:options: で . NumericSearch を指定すればOKでした。 extension String { static func checkVersion(lhs lhs: String, rhs: String) { switch lhs.compare(rhs, options: .NumericSearch) { case .OrderedAscending:

ios

iOSアプリのCrashログをsymbolicateする

iPhoneアプリのクラッシュログからクラッシュの原因を探す。 必要なもの クラッシュログ dSYMファイル クラッシュログを取得 クラッシュログ一覧を表示 Devicesウィンドウを開く Xcode Windows -> Devices (Shift+Cmd+2) デバイスを選択 View Device Logs でクラッシュログの一覧を表示 クラッシュログのエクスポート 該当アプリのクラッシュログをCtrl+左クリック(右クリック) Export Log で任意のディレクトリに出力 dSYMファイルを取得 Organizerを開く Xcode Windows ->

ios

Xibファイルでレイアウトを定義したUIViewControllerで*LayoutGuideを使う

XIBファイルで開発を進めているけど UIViewController のサブビューが UINavigationBar にめり込んでつらいという話をされたので対策を考えた。 XIBファイルベースで開発するUIViewControllerサブクラスは FromNibViewController のサブクラスとして実装することを前提として。 class FromNibViewController: UIViewController { // MARK: -- Statics static var kTopLayoutConstraint: String { return "TopLayoutConstraint" } static var kBottomLayoutConstraint: String { return "BottomLayoutConstraint" } // MARK: -- Properties

xcode

Swiftのコンパイルはストレスが溜まるので

SwiftでiOSアプリを作成しているとコンパイル速度が遅くてストレス溜まるなーというタイミングが多々あるのでコンパイル速度というかストレスを減らそうという対応を幾つか記載。 やったこと プロジェクトのコンパイル時間計測オプションを設定する Xcodeプロジェクトの Bundle Settings にある Swift Compiler - Custom Flags で -Xfrontend -debug-time-function-bodies を設定する BuildTimeAnalyzer を入れる BuildTimeAnalyzer プラグインをインストールする 現行バージョンではBuildTimeAnalyzerの更新中にビルドし直すとクラッシュするけど重いメソッドが見られるので便利。 InterfaceBuilderの自動コンパイルを止める StoryboardかXibファイルを開いてInterfaceBuilderが表示されているときに Automatically Refresh Views のチェックを外す。 Xcode -> Editor ->

ios

Xcodeでコードを書かずに角丸のボタンを作る

タイトルの通り、プログラムらしいことをしないで角丸ボタンを表示する 手順 角丸画像を用意する XcodeのAssetに画像を追加する 画像のスライス設定で可変領域を設定する 角丸画像を表示したいボタンの背景画像(Background image)に設定する コードで実装する 覚えてたら後で書く その他 動画のアップロードがイケてない。youtubeとかじゃないとうまくいかないのかも。

ios

iOS8,9の違いを幾つか その1

次があるかわかりませんが、その1。 UIView Class 再描画でよく使われるメソッド - (void)layoutIfNeeded; 深度が違うようです。iOS9だと再帰的に適応されるようですが、iOS8だと深度が1か2か。 再描画されないなーということがありました。 気づいた時はframeの変更をしようとした時でした。 NSLocale Class - (NSArray<NSString *>*)preferredLanguages 出力する。 NSLog(@"%@", [NSLocale preferredLanguages]); iOS8系 ( ja, en, "zh-Hans"

objc

[Objective-C] 特定の緯度経度と角度と距離を元に緯度経度を算出する(楕円あり)

現在地を起点として、特定距離の矩形を作成する。 みたいなことが必要だったので計算式を書いた(ほぼコピペ)。。。けど使われないことになった。 やってることとしては ある地点を中心とした半径Xメートル同心円上における角度Aの地点の緯度経度を求めよ(ただし地球は楕円形として扱うこと) みたいな感じでしょうか。文系な自分にはこういうのよくわからないです。。 結果として下記ソースでほぼイケるけど、浮動小数点数の演算ばかりなので誤差が気になるところ。メソッドのコメントに記載しているURLでJavascriptのソースがあったので、Objective-Cに書き直しただけって感じですが、一部変えています。詳細はソース見てもらえれば。 参考サイトではdo whileでループしているが この部分の動作を見てみたら、Javascriptでは精度を上げるようなループをしていたけど期待通りに実装する方法がわからなかったので、ループの中身を1度実行するだけに変更しています。 #import <CoreLocation/CoreLocation.h> #define EARTH 6378137.f #define EARTH_

ios

iOSアプリのDBをCoredataからRealmへ

現時点の最新バージョン v0.96.2 での内容なので、バージョンによって違うかもしれないです。 GUIをインストール ブラウザが無いと閲覧できない。最新バージョンのzipをDL。 公式の日本語ドキュメントは最新バージョン用ではない可能性があるのでgithubのURLから直接落とす方が安心。 https://github.com/realm/realm-browser-osx/releases/ Xcode Plugin XcodeでModelファイルを新規作成するにはPluginを入れると簡単になるらしい。 Xcode Pluginは公式ドキュメントにならってAlcatrazからインストールする。 Xcode Pluginのインストールディレクトリパスはこちら ${HOME}/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins Alcatrazのインストール コマンドラインから実行

xcode7

xcode7でNullabilityを定義 したヘッダにblocksをtypedef定義したらエラーが出た

typedef (^ SimpleBlock) (id obj); とかをconfig的な場所で定義して、いろんな場所で使っていた。 たまたまヘッダーファイルをがっつりいじる機会があったので、nonnullとかnullableとかも書いて、ヘッダの上の方で定義していたので存在を忘れていた。 そのままコンパイルしたらワーニングが出ていた。 pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) あ、すみません。と思ってnullableと書いてコンパイルしたらエラー。 unknown type name 'nullable' expected ')' こんな感じでいくつか。

ios

iOS7,8,9のアプリケーションライフサイクル

以前に作ったアプリがiOS9でうまく動かないという連絡を受けたので調査した結果、アプリケーションのライフサイクルが変更されたことによりイベントトリガと描画の関係が前後するというしょぼいミスをしていました。 悔しいので変化をまとめました。 具体的な問題の原因となった箇所はこちら。詳細は下のライフサイクルを見たらわかります。 -[AppDelegate applicationDidBecomeActive:] 検証したアプリの画面構成 UINavigationController FirstViewController SecondViewController(FirstViewController.navigationControllerにpushされる) iOS7 (7.1.2 // 起動 -[FirstViewController awakeFromNib] -[AppDelegate application:willFinishLaunchingWithOptions:] -[AppDelegate application:didFinishLaunchingWithOptions:] -[FirstViewController viewDidLoad]

xcode

Xcode7からのBundle Identifier定義

--- 追記@2016/12/6 こっちにXcode8での設定方法を書きました --- 追記ここまで Xcode6系まではinfo.plistで直接定義する形だったけど Xcode7からはProjectファイルで定義するようになって、info.plistのbundle identifierの項目はこんな感じになっていた(Xcodeのマイグレーションをするとこうなるということで。 $(PRODUCT_BUNDLE_IDENTIFIER) メリット ビルド設定(Build Configuration)でバンドルIDが変更できるようになった。 Debugビルド、Releaseビルド、AdHocビルドなどでバンドルIDが変更できるのでターゲットを無駄に追加する必要が無くなった。 デメリット 理解していない人がinfo.plistを書き換えたら死ねる。 下手に書き換えられたら別アプリになるから。。。

ios

iOS9のFontFamilyName

iOS8系でフォントの一覧を出したので、iOS9でもやっておく。 なんかfamilyNamesの中身が無いものもいくつかあったぽい(たぶんCJKとか言語に依存するものだと思う)。 取得方法 familyNameからfontNameを取得する。 for (NSString *familyName in [UIFont familyNames]) { for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) { NSLog(@"%@", fontName); } } 確認環境 iPhone Simulator (iOS9) 結果抜粋 Copperplate-Light Copperplate Copperplate-Bold IowanOldStyle-Italic IowanOldStyle-Roman

ios

GoogleAnalyticsを組み込んだiOSアプリがiOS9実機ビルドできなかった

表題の通りGoogleAnalyticsを組み込んだiOSアプリのiOS9実機ビルドでエラーが出た。 とりあえず何も考えないでGoogleAnalyticsを最新版に更新したが変わらなかった。iOS9対応というかXcode7対応。 https://developers.google.com/analytics/devguides/collection/ios/v3/sdk-download?hl=ja エラー内容 ld: '/Users/xxxx/path/to/app/Libs/GoogleAnalytics/libGoogleAnalyticsServices.a(TAGDataProvider.o)' does not contain

ios

iOSエンジニアに知っていてほしいブレークポイント

アプリを改修するiOSエンジニアが知っていると得をするブレークポイント。 デバッグするときにブレークポイントを使用しないエンジニアはあまりいないと思う。 アプリを改修することになったとき、元々自分が実装したアプリ以外は画面の構成やイベントハンドリングが自分の思想とは全然違うことがあって、どこで画面遷移が行われているのか。どの画面がいま表示されている画面なのかわからないということはよくある。 そんなときに使うブレークポイントがSymbolicBeakpoint。 Xcodeで「⌘+7」を押してブレークポイントを表示して、ウィンドウ左下の+ボタンから作成する。 [UINavigationController pushViewController:animated:] [UIViewController presentViewController:animated:completion:] こんな感じで設定しておけば、このクラスメソッドやインスタンスメソッドが実行されるときにブレークポイントが作動して止まってくれる。 上記の場合だど実際にはUIKitのメソッドで停止するのでスタックを辿る必要があるけど、 どのクラスのどのメソッドから画面遷移のイベントが実行されたか判断できる。

ios

UITabBarの色を変える

UITabBarControllerのデザインをちょこちょこ調整する必要があった。 またいつか使いそうな気がするのでメモ。 この設定はiOS7.1系以降なら問題なく動くと思う。7.0系は問題があったようななかったような。 + (UIImage *)imageFromColor:(UIColor *)color size:(CGSize)size { CGRect bounds = CGRectZero; bounds.size = size; UIGraphicsBeginImageContext(bounds.size); CGContextRef contextRef = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(contextRef, [color CGColor]); CGContextFillRect(contextRef, bounds); UIImage