カテゴリー別アーカイブ: Swift

【Swift4】【Objective-c】SKStoreReviewController でアプリ内レビュー

最近流行りのアプリの中でレビュー(アプリの評価)をつけてもらうやつを調べてみた。

参考サイト
SKStoreReviewController を単純な条件で出すだけでも好意的なレビューが増えて良かった
SKStoreReviewController で App Store の評価数が急増した話 – wootan’s diary

機能としてはiOS10.3以降が対応のようです。
表示されるのは年に3回まで。
有意の時点で呼び出して、年に3回に達していないと表示されるらしい。
つまり、何回起動したときとか、そういう条件をつけて、レビューの請求をされてもおかしくない、
できれば好レビューが貰えそうな時に表示されるようにするのが良いっぽい。

コードとしてはStoreキットをインポートして使う。

Swiftの場合。

objective-cの場合。

一度この表示が出て評価を送信すると、その後は出なくなるのか、それとも、直後でも呼び出されるとまた表示されてしまうのか、そのへんの詳しい挙動がわからんのでそれなりの対応が必要そうです。

と、ゆーことで、いま手入れしてるobjective-c用にコードを書いてみた。

最初は10回呼ばれたら、その後は100回呼ばれる毎にレビューが請求されます。

あ、バージョンでの切り分けはこちらを参考にしました。
Objective-C で OS バージョン判定を簡潔に行う方法

【Swift】ちょっと珍しいエラー?【libclosured.dylib】

先日、アプリをアップデートして課金機能を実装しました。
ユーザーから課金しても良いので広告を外してほしいと熱望されていたのです。
しかし、ただでさえプログラミングに慣れていないのに、課金はかなり理解し難く、たいへん手を焼きました。
おかげで途中数ヶ月放置なんてこともあり、実装できるまでに1年近くかかりました。

で、Xcodeのシミュレータでも、実機でもsandBoxを使って問題なく課金が出来ることを確認して、Appleの審査に提出しました。
アプリの説明にも堂々と「課金で広告が外せるようになりました」と書いて。
最近は審査の時間がどんどん短くなってるようで、今回はびっくりの24時間切り、18時間位で無事リリースされました。

が、そこで問題が起こりました。
設定の画面から課金の画面に行くと、フリーズしてクラッシュするのです。
何度試しても同じ、実験機でも、嫁のiPhoneでも同様でした。
もう一度、Xcodeからビルドして動作確認をしてもこちらは問題なし。
appSotreからダウンロードし直してみるとやっぱりクラッシュ。
こんなんどうやって、デバグしたらいいのと、血の引く思いでした。
毎度、Appleに審査出して通ってから実地確認ってわけにも行かないしね。^^;
あんなに堂々と課金できますよって書いちゃったのに。/(^o^)\

で、まあ、とりあえずいろいろ検索して
下記サイト見つけエラーログが調べられることがわかりました。
swift – 原因のわからないバグの特定方法について – スタック・オーバーフロー

エラーログを取ってみるとズラズラとログが表示されて、

という感じで、最後は
0x1ad277000 – 0x1ad2a7fff libclosured.dylib arm64 /usr/lib/closure/libclosured.dylib
で終わっていました。

よくわからんけど、/usr/lib/closure/libclosured.dylib このあたりが怪しいかと検索しまくり。

日本語のページでは全く引っからなかったけど、海外のサイトではcrashという文字とともにいくつか引っかかりました。
CFNetwork crash with iOS 11.3.1 |Apple Developer Forums
My app crash with Exception Type:  EXC_CRASH (S… |Apple Developer Forums
Crash in iOS 11.1 | GeoNet

などなど…。

英語はよくわからんが、総じて見ると、原因不明なんだけどOSの問題ちゃうん?って感じでした。

で、AppleDeveloperに電話で聞いても見たのですが、症状の再現はされるけれど、原因はわからんと。
こっちでは無理なので、テクニカルサポートかフォーラムで聞いてみてくれと。
どっちも英語やん。\(^o^)/オワタ

仕方なしに、コードを見直してみたり、App Store Connectを見直してみたり、
、、、してたら、App Store Connect のApp内課金のページですっごい違和感が!

あれ?課金コンテンツって審査用のスクリーンショットで必須だよね?/(^o^)\
でも、設定されてないよね。/(^o^)\

【Swift】ちょっと珍しいエラー?【libclosured.dylib】

メタデータが不足って書いてあると審査用のスクリーンショットがなかったりします。

よくよくアプリの設定を見たら、Xcodeでもin-App purchaceもオンになってないし、全然課金が動作する状態じゃなかった。/(^o^)\
Xcodeのin-App purchaceがオンになっててスクリーンショットがなかったりしたらリジェクトもされたんだろうけど、すべて後回しにして数ヶ月放置している間にそういうこともすっかり忘れていたようです。
そりゃ課金の設定無いのに、プロダクト情報取りに行ったらフリーズもするわ。^^;
しかし、よくアプリの審査通ったな。/(^o^)\

で、スクリーンショットを撮って、App内課金の設定もして、速攻で再度審査に提出しました。

まあはよ気づいてよかったよ。
こんなこともあるんだね。
うじゃうじゃ。

【Swift4】Google Analytics と eコマース?

SwiftでGoogle Analytics で eコマースを利用しようとしたが、ワケワカラン。
そもそもeコマースがわかってないんだが。
とりあえず課金があったらその情報を受け取れるようにしてみたい。

とりあえず、まずここの説明がSwiftに対応していない。(# ゚Д゚)
e コマース トラッキング – iOS SDK  |  iOS 向けアナリティクス  |  Google Developers

コピペだが、このコードがSwift化できれば良いんだと思う。

参考にしたのがこちら
ios – Issue with Google Analytics in Swift 2 or 3 – Stack Overflow
と、こちら
iOSアプリでもGoogleAnalyticsでがっつり計測する実装方法【総集編】 | Nagisaのすゝめ

なんだかんだイジって、
Xcodeに文句言われないように変更して出来たのがこの形。

とりあえず自分用。
うまくいかなくったってしーらないしーらない。
うじゃうじゃ。/(^o^)\

【Swift4】tabbarとnavigationControllerを使ってる時のマイナーな?戻り方。

Tabbar Controllerでつながった、タブAの画面とタブB1の画面があり、タブBからはnavigationControllerをつかってタブB2の画面に遷移できるとする。
画面B2に居る時にtabbarでタブAに移動して、またタブBに移動しようとすると、タブB2に移動してしまう。

一旦、タブAに移動してタブBに移動するとき、自動的にタブB1に移動するようにしたかった。

言葉にするとすごくわかりにくい。orz

結論から書くとタブB2の画面が消えたあとにnavigationControllerで戻る指示をすれば良い。

こんな感じで。
うじゃうじゃ。

【Swift4】UIScrollViewで電子書籍風に。

UIScrollViewを使って電子書籍風?な感じで見れるものを作ってみました。

参考サイト
[iPhone] UIScrollView ページ スクロール
【Swift】UIScrollViewの使い方。大きい部品をスクロールして見る。 | はじはじアプリ体験記
【Swift】UIScrollViewとUIPageControlを使ってページを移動する方法 | はじはじアプリ体験記
UIScrollView、UIKit座標計算系に関しての復習 – これが最後じゃないからね

基本条件
・表示させる画像ファイルを用意する。
・画像のサイズは多少、大小してもscrollViewの幅にリサイズ、画面中央に配置。
・漫画のように右から左へ見ていく。
・1画面1ページ。

UIScrollViewについて。
UIScrollViewはいろいろとサイズのプロパティがあってややこしい。

とりあえず参考サイトから真似てプロパティを説明する画像を作ってみた。
【Swift4】UIScrollViewで電子書籍風に。

UIScrollViewに使われるサイズは大きく分けて2つ。
frameとcontentSizeだ。
frameのサイズは画面に表示される「枠」のサイズ。
contentSizeが枠のなかに表示される「移動可能な領域」のサイズ。
イメージとしてはframeの上にcontentSizeが乗ってる感じだけど、
実際にはcontentSizeのうえにframeがあってそこから覗き込んでる感じなのでややこしく感じる。

frameには
frameの位置座標をあらわす(frame.origin.x , frame.origin.y)というプロパティと
frame.size.widthという幅と、
frame.size.heightという高さのプロパティを持っている。
frame.originはiPhoneの画面の起点からの距離というところに注意。

contentSizeは
contentOffset.x , contentOffset.yというscrollViewに対する位置情報と
contentSize.widthという幅と、
contentSize.heightという高さのプロパティを持っている。

contentInsetは今回使わないので割愛。

今回は電子書籍風ということでscrollViewのframeとcontentSizeの高さを揃えて、contentOffset.xの値が変動することによって画面が横スクロールするイメージです。
【Swift4】UIScrollViewで電子書籍風に。

ではまず、StoryboardでViewControllerを開き、ScrollViewを配置します。
【Swift4】UIScrollViewで電子書籍風に。

AutoLayoutで位置を決めて、Paging Enabledにチェックを入れます。これでscrollViewがページ単位で動くようになります。

次いで、Assetsに画像を放り込みます。
【Swift4】UIScrollViewで電子書籍風に。

コードの記述

・AutoLayoutの処理を待ってviwDidApearから処理を始めます。
・scrollViewのサイズが決まったら高さと幅を取得。
・scrollView幅に合わせて画像のサイズを変更してsubviewに貼っていく。
・subviewを配列に取り込んで順番を逆転。
・順にscrollViewの幅ずつずらしていく。
・scrollViewの幅×画像の数をcontentSizeの幅にする。
・contentSizeの高さはscrollViewの高さと同じ。
・scrollViewの初期位置を一番右の画像に持ってくる。

①の時点でのイメージはこんな感じ。
【Swift4】UIScrollViewで電子書籍風に。

contentSizeはまだ指定していないので存在しないか(0,0)なので画面は動きません。

画像の順番を並べ替えて右へずらしてframeを初期位置へ移動させて、
最終的に起動した時のイメージは②でこんな感じ。

【Swift4】UIScrollViewで電子書籍風に。

contentSizeの範囲をflameの幅で左右にページ移動します。
一応こんな感じでscrollViewが使えました。

うじゃうじゃ。

【Swift4】効果音のクラスを作ってみた。【AVAudioPlayer】

ずーーっと以前にSwiftで音を出すのはやってみた。
【Swift3】【AVAudioPlayer】音を出してみる。 | iPhoneアプリ備忘録

最近、ちょっとまた効果音を出したくて勉強し直してみた。
効果音を出すにはAudioServicesPlaySystemSoundを使う方法もあって、連打できたりするのは良いのですが、
iPhone側の音量で調節ができないという欠点もあり、AVAudioPlayerを使って連打も出来るようにクラスを作ってみた。

ちなみにクラスとか作るの初めてなのでなんか間違ってても生暖かく見守るか、優しく教えてもらえるとありがたいです。(-人-)

さて、参考にしたのはこちらのサイト。
ARC環境下でAVAudioPlayerを使い柔軟かつシンプルにサウンドを再生する方法

これをSwiftで書いてみたいと思います。

まず、AVAudioPlayerを使うにはAVFoundation.frameworkが必要です。
TARGET>Generalで追加しておきます。

音声ファイルも用意してプロジェクトナビゲータに放り込んでおく。
とりあえずファイル名は「hit.mp3」とする。

んでは、SEManagerというNSObjectのクラスを作ります。

これで音を鳴らすクラスが出来た。
インスタンスを配列に入れて削除する辺り、実はよく分かってない。/(^o^)\
do とか、try とか、throwsとかも理解していない。
動いてるから良しとしてほしい。(^_^;)

んで、音を鳴らして!っていう側。
ボタンアクションでSEManagerを呼び出します。

SEManagerに投げる音声ファイルでいろいろと音が鳴らせるので汎用性は高いように思います。
あ、インスタンスとか、オブジェクトとかよく理解できてませんので、なんかおかしい所あるかもしれません。
動いてるから良しとして(以下ry

ま、そんな感じで自分用の備忘録です。
うじゃうじゃ。

【Swift4】objective-cからSwiftのクラスを呼び出す。

おぶしーからすいふとに切り替えて暫く経ちますが、古いアプリなど丸っとスイフトに書き換えるのは面倒なので、
objective-cはそのままで、新規クラスはSwiftでと混在させてます。

んで、objective-cからSwiftのクラスを呼び出す時にちょっと詰まったんで備忘録。

参考サイト
Objective-CコードからSwiftのクラス/プロトコルを使う方法(フレームワーク開発編)
Objective-CベースのプロジェクトからSwiftのクラスを呼び出す
SwiftとObjective-Cの相互利用する際の注意

例えば、
hogehogeというアプリがあって、
higehige.h higehige.m というobjective-cのクラスが有って、
hagehage.swift というswiftのクラスがあるとする。

higehige.m で hagehage.swiftクラスを使いたいので、適当にインポートしてみた。

エラーが出た。(´・ω・`)ショボーン

ネットで調べて、-Swift.hを着けたら良いのね!(`・ω・´)シャキーン

あれ?(´・ω・`)

ムキー!なんで通らんのや!/(^o^)\

じっくり調べなおすと、、、「プロダクト名」-Swift.h なのか…。orz

これでよかったようです。/(^o^)\
クラス呼び出すんやからクラス名だと思うやん…。(´・ω・`)

ちなみに呼ばれる側は

のように@objcMembersをつけるか、メソッドの前に @objc をつけておくようです。

他にもハマりどころはありそうなので他サイトも参考に。
うじゃうじゃ。

2018/07/10追記
上記のようにswiftファイルをインポート出来るようになりました。
で、次の記事にあるSEManager.swiftで音を鳴らしたいのですが、
objective-cからSEManager.swiftのメソッドを呼び出そうとするとエラーが!!

SEManager.swiftのplaySoundメソッドは引数があるのでobjective-c側からはplaySoundWithSoundNameで呼び出します。
xcodeの変換サポートでも候補に出るし、問題なく認識していそうなのですが、どーやってもNo visibleのままです。

よくわからないまま試行錯誤を繰り返すこと丸一日、SEManager.swiftのplaySoundメソッドの中にある’throws’を消すと認識されました。
throws,do,try,catchというのはよく分かってないですがAVAudioPlayerを使う時にXcodeからつけろーと言われます。
このthrowsを消すと、別のswiftファイルからplaySoundメソッドを呼び出す所で黄色三角のエラーが出ますがビルドは出来ます。
なんとも明確な解決策が見いだせませんでしたが、とりあえず動いたので良しとしつつ、自分の無能を呪っときましょう。/(^o^)\

【Swift】レイアウトがずれる。【AutoLayout】追記あり。

原因が分かってからネットを検索すると情報はいっぱい出てくるんですけどね。
原因にたどり着くまでが長かった。orz
忘れると困るので備忘録。

参考サイト

http://rindatetu.hatenablog.jp/entry/2016/03/06/154946

症状としてはStoryboardでAutoLayoutで指定したスクロールビューがおかしい。
機種(画面サイズ)によって位置がずれる。

結果的にはAutoLayoutで指定したビューを元にviewDidLoadメソッドで更に描画指定をしようとしたからずれたようだ。

自分が理解しているviewControllerのライフサイクルは以下のような感じ。

・viewDidLoad
最初に一回だけ呼ばれる。
初期設定とか何でも放り込みがちだよね。

・viewWillAppear
開くたびに呼ばれる。
他の画面で設定したものを毎回画面に来る度に反映させたいときなどにつかう。

・viewDidAppear
画面の表示、レイアウトが終わった所で呼ばれる。

・viewWillDisappear
他の画面に遷移する直前に呼ばれる。

・viewDidDisappear
他の画面に遷移したあとに呼ばれる。

今回はAutoLayoutの処理が終わったあとに更に描画処理をする必要があったため、viewDidAppearに処理を書くことで対処できた。
しかし気づくまでに3日もかかったとか…。orz

追記
さらにその後問題が見つかった。
viewDidAppearにレイアウトの処理を書くと、毎回開くたびにレイアウトがやり直される。
今回はscrollViewで電子書籍風のページを作ったが、別のviewに行って戻ってくると最初のページに戻ってしまう。

この問題の解決方法がこちら
参考サイト
[Swift] viewDidLayoutSubviewsで初回だけ処理をしたい | 黒ごまのおむすび

よくわからないが lazy というのあり、これを使うと
初回一回のみの処理となるらしい。

まだよく理解できてないが、一応思ったとおりの動作になったので良しとしよう。
うじゃうじゃ。

【Swift】CGFloat、CGPoint、CGSize、CGRect

よくわかんないので自分用まとめ。
よくわかんないので超ざっくりです。(^_^;)

参考サイト
Swiftで遊ぼう! – 249 – UIViewの座標システム: iOS12 – Swiftで遊ぼう! on Hatena
Swiftで遊ぼう! – 299 – Scroll Viewの座標システム – Swiftで遊ぼう! on Hatena
基本を理解するために(CGPoint,CGSize,CGRect,frame)

CGFloat
これは座標(x,y)や画像のサイズ(width,Height)などに入れる「数値」が入る型。Double型もしくはFloat型から変換できる。

CGPoint
これは座標を表す型。.xと.yのプロパティを持っている。もちろん(x,y)はCGFloat型。

CGSize
これはそのままサイズを表す型。.widethと.heightのプロパティをもっている。もちろんCGFloat型。

CGRect
これは、座標(CGPoint)とサイズ(CGSize)を持つ型。

まだまだよく分かってないっすね。/(^o^)\

【Swift4】NotificationCenterの備忘録。

参考ページの劣化コピーの備忘録です。
詳しくは参考ページを見てもらったほうが良いかと。(-人-)

以下参考ページ。
iOSTraining/3-4_Notification-NotificationCenter.md at master · mixi-inc/iOSTraining · GitHub
[Swift3.1] NotificationCenterを使ってViewController間でイベント通知を送る – Qiita

NotificationCenterを使って通知のやり取りをしたい。

☆まずは通知を受け取りたい側にaddObserverの登録

viewDidload等で登録をしておきます。

通知を受け取って動作するメソッドcatchNotificationを実装

☆通知を送りたい側のVCに通知をPostする処理を書く。

通知を送りたい箇所でPost

多分これで通知が送られるはず。/(^o^)\

参考サイトではNotificationCenter.defaultをインスタンスにしてたり、
Extentionでの拡張により .myNotificationName というのを使っていたりしますが、
僕の頭ではよく理解できませんでした。/(^o^)\
多分あれだ、いっぺんに通知の名前を変更する時に打ち間違いや、やり残しをなくすためだな。/(^o^)\