しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

【iOS11】設定アプリ内にある自分のアプリの設定画面へ遷移する

iPhoneの設定アプリには、下のように自分のアプリの設定ページが用意されています。
今回はここへ直接遷移する方法について調べました。

f:id:llcc:20180720173134p:plain

自分のアプリの設定画面への遷移方法

遷移方法は下の通りです。

if let url = URL(string: UIApplicationOpenSettingsURLString) {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}

UIApplicationOpenSettingsURLStringは文字列型で、自分の設定ページへの遷移URLが入っています。

print(UIApplicationOpenSettingsURLString) // → app-settings:

Railsでcrontabを管理できるwheneverというGemを使ってみる

Railsを使っていると「日時バッチ」「1時間に一度の処理」など定期的に実行したいタスクが出てきます。
管理方法としては普通にcrontabに書き込んだりJenkinsなどを使ってそれらのタスクを管理する方法があります。
しかし可能ならRailsプロジェクト上で実行時間なども管理したいです。

そういった時に使えるGemがwheneverです。
これを使うと下のようにRubyでcrontabの管理ができます。

every :day, at: '12:20' do
  runner 'MyModel.execute'
end

every :sunday, at: '12:30'
  runner 'MyModel2.execute'
end

github.com

wheneverを使う準備

インストールはBundlerを使います。

gem 'whenever'

インストールが終わったらwheneverizeコマンドでwheneverの初期化をします。

wheneverize

f:id:llcc:20180716215520p:plain

実行するとconfig/schedule.rbというファイルが作られます。
ファイルの内容は下の通りです。

# Use this file to easily define all of your cron jobs.
#
# It's helpful, but not entirely necessary to understand cron before proceeding.
# http://en.wikipedia.org/wiki/Cron

# Example:
#
# set :output, "/path/to/my/cron_log.log"
#
# every 2.hours do
#   command "/usr/bin/some_great_command"
#   runner "MyModel.some_method"
#   rake "some:great:rake:task"
# end
#
# every 4.days do
#   runner "AnotherModel.prune_old_records"
# end

# Learn more: http://github.com/javan/whenever

wheneverの使い方

まずは先程作られたconfig/schedule.rbに定期実行したいタスクを書きます。
下は4日おきにMyModelのcreate!を呼び出すタスクです。

every 4.days do
  runner "MyModel.create!"
end

タスクを書いたらcrontabにどんな形で書き込まれるか確認をします。
確認にはwheneverコマンドを使います。

whenever

wheneverコマンドを実行すると下のようにどのようにcrontabに書き込まれるかが表示されます。

f:id:llcc:20180716220541p:plain

crontabへの反映もwheneverコマンドを使います。
下のように--update-crontabを付けて実行します。

whenever --update-crontab

実行後crontab -lで確認するとしっかり書き込みができている事が分かります。

f:id:llcc:20180716220757p:plain

wheneverのフォーマット

wheneverではデフォルトでcommand, rake, runner, scriptというメソッドが用意されています。
実行結果はそれぞれ下の通りです。

every 4.days do
  command "bundle install" # → /bin/bash -l -c 'bundle install'
  rake "my_task" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && RAILS_ENV=production bundle exec rake my_task --silent'
  runner "MyModel.create!" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && bundle exec bin/rails runner -e production '\''MyModel.create!'\'''
  script "my_script" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && RAILS_ENV=production bundle exec script/my_script'
end

自分で上記以外のメソッドを追加する事もできます。

job_type :my_job, "cd :path && :bundle_command rake :task"

every 4.days do
  my_job "my_task" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && bundle exec rake my_task'
end

実行時間の書き方も色々な種類があります。

下のように文字列でcrontabと同じ形式に書く事ができます。
非常に分かりやすい書き方です。

every '0 0,1,2 * * *' do # → 0 0,1,2 * * *
  runner 'MyModel.execute'
end

毎日決まった時間に実行する場合は下のような書き方も分かりやすいです。

every :day, at: '12:20' do # → 20 12 * * *
  runner 'MyModel.execute'
end

特定の曜日だけ実行する事もできます。

every :sunday, at: '12:30' do # → 30 12 * * 0
  runner 'MyModel.execute'
end

「アプリ開発のためのUX講座」まとめ

「アプリ開発のためのUX講座」という動画講座がとても面白かったので、学んだ事や感想をまとめてみました。
動画はSchooの有料会員限定ですが、資料は下URLから見る事ができます。

schoo.jp

そもそもUXってなにか?

f:id:llcc:20180714160547p:plain

授業で初めて知ったんですが、実はUXはISOで定義されています。
授業では「サービスに接した時に感じるきもち」という形で噛み砕いて紹介されていました。

UXの種類

f:id:llcc:20180714161052p:plain

この授業ではUXを4種類に分けて紹介していました。
それぞれ下のような内容です。

予期的UX

サービスと接する前の体験。
「CMを見て気持ちが盛り上がる」「友達から紹介されてやりたくなる」など。

一時的UX

サービスを使って感じた体験。
「デザインがきれい」「アニメーションがおしゃれ」「特定の機能が便利だった」など。

エピソード的UX

サービス終了後の体験。
「使ってみて便利だった」「ゲームを遊んで楽しかった」など終了後に振り返る体験。

累積的UX

継続してサービスを使うことで起こる体験。
「ついつい起動してしまう」「次に使うのを心待ちにする」など。
これは一時的UXを積み重ねる事で起こる。

ユーザーに継続して使ってもらう為の工夫

f:id:llcc:20180714161839p:plain

ユーザーにサービスを継続利用してもらう為には、できるだけ強い「一時的UX」を体験してもらう事が重要だと紹介されていました。
弱い感動を連続して与えるのではなく、強い感動を与える事でファンになってくれる人が増えると話していました。

同時に、「一時的UX」をなるべく早く与える事も重要です。

「アプリ開発のためのUX講座」まとめ

「早く強い「一時的UX」を与える」という事を今まで意識してなかったので、目からウロコでした。
今まで自分は「使いにくい所を減らしてユーザーの離脱を防ぐ」って事を考えてアプリを作っていたので、これからは「どこで感動してもらうか」という事も考えようと思いました。

それからUXを4つに分類した事も面白かったです。
今までは「一時的UX」しか意識してなかったので、今後余裕があれば他のUXについても考えてみたいと思います。

はてなブログの過去記事にカテゴリーを付ける

はてなブログの過去記事にカテゴリーが全然付いてなかったので付ける事にしました。
カテゴリーなしは百記事以上あるので少しでも楽になるように工夫しつつ実施しました。

f:id:llcc:20180706221643p:plain

まずはエントリー一覧ページに移動します。

https://blog.hatena.ne.jp/llcc/llcc.hatenablog.com/entries

全ての記事を一気に直したいので「次のページ」をひたすら押して全部の記事を出します。

f:id:llcc:20180706221845p:plain

押し続けるのが大変な下コードを実行します。

$(".js-load-next-page").click()

次に「カテゴリーなし」のものだけ表示するようにします。
機能としては用意されてないので下コードを実行します。

$("tr").filter(function() { return $(this).find(".blog-category-name").length == 1 }).each(function() { $(this).remove() })

これでカテゴリーがないものだけを取得できたので地道に一括カテゴリー設定をしていきます。

f:id:llcc:20180706222824p:plain

LAContextのbiometryTypeがnoneになる問題

LAContextクラスのbiometryTypeプロパティーを使うと端末が指紋認証に対応しているか顔認証(FaceID)に対応しているかを判定する事ができます。

LAContext().biometryType == .faceID
LAContext().biometryType == .touchID

LAContextのbiometryTypeで起こった問題

しかし顔認証対応の端末で上のコードを実行してもtrueになりません。

LAContext().biometryType == .faceID // → false
LAContext().biometryType == .touchID // → false
LAContext().biometryType == .none // → true

LAContextのbiometryTypeで顔認証を判定する方法

判定するためには、canEvaluatePolicyメソッドを一度実行する必要があります。
こうすればfaceID対応している端末かを判定できます。

let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
    print(context.biometryType == .faceID) // → true
}

ドキュメントの方にもcanEvaluatePolicyが呼ばれたタイミングで値がセットされると書かれています。

This property is set when canEvaluatePolicy has been called for a biometric policy.
The default value is LABiometryTypeNone.

指紋認証だとどうなるか

iPhone8など、指紋認証対応している端末で検証しても同じような結果になりました。

LAContext().biometryType == .faceID // → false
LAContext().biometryType == .touchID // → false
LAContext().biometryType == .none // → true

UnityでスクリプトからTexture2Dを読み込む(C#)

UnityでSpriteのTextureをスクリプトで動的に変更する方法です。

Textureの配置場所

読み取りたいTextureはResourcesフォルダに入れる必要があります。

f:id:llcc:20180628134744p:plain

詳しくは下ページのResourcesに載っていました。

docs.unity3d.com

Textureの読み込み

Textureの読み込みは下の通りです。
Resources.Loadを使って先程配置したTextureを読み込んでいます。

テクスチャのパスにはフォルダ名(Resources)は含める必要はありません。

(Texture2D)Resources.Load($"enemies/enemy1");

はてなブログのSSL対応でカスタムシェアボタンが動かなくなった時の対策

タイトルの通り、はてなブログのSSL化でカスタムシェアボタンが動かなくなったので対策を書いていきます。
利用させて頂いたカスタムシェアボタンは下サイトのものです。

www.yukihy.com

SSL化で発生した問題

下のようにはてブ数とFacebookのシェア数がずっとローディングのままになりました。

f:id:llcc:20180627150028p:plain

対応方法

1つ目の修正点は下のタグです。
http://code.jquery.com/jquery-1.9.1.min.jsのhttp://となっている箇所をhttps://に変更しました。

<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

2つ目の修正箇所はJavascriptの下処理です。
ここのhttp://api.b.st-hatena.com/entry.count?callback=?となっている部分をhttps://b.hatena.ne.jp/entry.count?callback=?に変更しました。

jQuery.ajax({
  url:'http://api.b.st-hatena.com/entry.count?callback=?',
  dataType:'jsonp',
  data:{
    url:url
  },
  success:function(res){
    jQuery( selcter ).text( res || 0 );
  },
  error:function(){
    jQuery( selcter ).text('0');
  }
});

以上で対応完了です。
無事にはてブ数とシェア数が取れるようになりました。

f:id:llcc:20180627150507p:plain