はじめに
UniversalLinksでディープリンクを実装し、リンククリックでアプリを起動する方法をメモします。ios9より対応しているため、それ以前のバージョンは考慮しません。(実際はカスタムURLを使うと実装が可能です。iOS9以前を対象ととする場合はバージョンにより切り分ける処理が、アプリ側もサーバ側も必要になります。)
やりたいこと
1)既にアプリがインストールされている場合はアプリを起動
2)アプリがインストールされていない場合はストアを起動(アプリのインストールを促す)
ドキュメント
https://developer.apple.com/jp/documentation/General/Conceptual/AppSearch/UniversalLinks.html
UniversalLinksについて
引用:
ユニバーサルリンクに対応すると、iOS 9ユーザがウェブサイトのリンクをタップしたとき、Safariを経由せず、インストール済みアプリケーションに直接遷移させることが可能になります。もし未インストールの場合はSafariが起動し、ウェブサイトが開きます。
iOS9より前のバージョンのUniversalLinks挙動
引用:
iOS 9.0よりも古いバージョンであれば、ユニバーサルリンクをタップするとSafariが起動し、リンク先ページが開きます。
新規アプリの場合はios9以前のバージョンは現時点で5%以下のため捨てて良いと思います。
https://developer.apple.com/support/app-store/
UniversalLinks実装について
UniversalLinksの実装にはアプリ側とサーバ側どちらも設定を行う必要があります。サーバ側のみ対応してもアプリ側で対応しないとディープリンクは有効に働きません。
サーバ側の実装:
1)apple-app-site-associationファイルの作成と設置
アプリ側の実装:
1)com.apple.developer.associated-domainsエンタイトルメントに該当するドメインのエントリを追加する
2)ディープリンクをハンドリング
[サーバ側] 1)apple-app-site-associationファイルの作成と設置
アプリとサーバで関連付けを行い信頼をあげるための処理を入れる必要があります。
apple-app-site-associationファイルを作成し、サーバに設置し、アプリ側でインストール時にダウンロードを行い中身の整合性チェックを行いセキュアな接続をしています。
引用:
apple-app-site-associationファイルは、ドメインごとに内容を変えて用意する必要があります。たとえばapple.comとdeveloper.apple.comには、それぞれ独立にapple-app-site-associationファイルを用意します。この2つのドメインは、提供するコンテンツが異なるためです。一方、apple.comとwww.apple.comは、同じコンテンツを提供するので、関連づけファイルも同じで構いません。ただし、両方にこのファイルを置く必要があります。iOS 9.3.1以降で動作するアプリケーションの場合、圧縮されていないapple-app-site-associationファイルのサイズは、署名済みファイルであるかどうかにかかわらず128KBを超えないことが要件になります。
apple-app-site-associationファイルにドメイン情報を設定します。
ファイルはjsonですが拡張子はつけるとうまく動作しないようです。
設定例:
{
“applinks”: {
“App”: [],
“details”: [
{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
},
{
“appID”: “ABCD1234.com.apple.wwdc”,
“paths”: [ "*" ]
}
]
}
}
引用:apple-app-site-associationファイル記述に関する説明文
apple-app-site-associationファイルには「apps」キーが必須です。その値は、リスト6-1のように、空の配列でなければなりません。detailsキーの値は辞書の配列で、ウェブサイトがサポートするアプリケーションごとに辞書を用意します。システムは辞書が配列中に現れる順序に従ってアプリケーションを照合します。その結果、ウェブサイトのパスによって、処理を引き受けるアプリケーションが決まります。
アプリケーションごとに用意する辞書には、appIDキーとpathsキーが必要です。appIDキーの値はチームIDまたはApp IDの接頭辞であり、このプレフィックスの後ろにバンドルIDが付加されます(appIDの値は、アプリケーションのビルド後、アプリケーションのエンタイトルメントに含まれている“application-identifier”キーに関連づけられているものと同じ値です)。pathsキーの値は、ウェブサイト中のどのパスを当該アプリケーションが処理し、どのパスを当該アプリケーションには関連づけないかを表す文字列の配列です。ユニバーサルリンクとして処理しない領域を指定するには、パス文字列の先頭に“NOT ”を付加します(Tの後ろには空白文字を入力)。たとえば、リスト6-1に示したapple-app-site-associationファイルの場合は、paths配列を以下のように書き換えることで、ウェブサイトの/videos/wwdc/2010/*領域がユニバーサルリンクとして処理されないように設定できます。
“paths”: [ "/wwdc/news/", "NOT /videos/wwdc/2010/*", "/videos/wwdc/201?/*"]
paths配列に含まれている個々のパスは、記述されている順に評価され、肯定または否定の検索文字列に一致するものが見つかった時点で評価が中止されます。したがって、優先度の高いパスを低いパスよりも先に記述する必要があります。なお、照合するのはURL中の「パス」部分だけで、クエリ文字列、フラグメント識別子など、その他の部分は無視します。apple-app-site-associationファイルには、ウェブサイトのパスをさまざまな方法で記述できます。その例をいくつか示します。
*を使って、ウェブサイト全体を指定する。
具体的なURL(たとえば/wwdc/news/)を記述して、リンクを個別に指定する。
具体的なURLに*を付加して(たとえば/videos/wwdc/2015/*)、ウェブサイトの特定のセクションを指定する。
任意の部分文字列に合致する「*」のほか、任意の1文字に合致する「?」も指定できます。この2つのワイルドカードをひとつのパスの中で用い、「/foo/*/bar/201?/mypage」のように記述することも可能です。
[アプリ側] 1)com.apple.developer.associated-domainsエンタイトルメントに該当するドメインのエントリを追加する
サーバとの関連付けのため、ドメインをエントリします。
xcodeのcapabilitiesから設定します。
引用:
com.apple.developer.associated-domainsエンタイトルメントに、アプリケーションがユニバーサルリンクとして扱うドメインの一覧を記述します。Xcode上で、「Capabilities」タブの「Associated Domains」セクションを開き、該当する各ドメインのエントリを追加してください。applinks:を接頭辞として付加し、たとえばapplinks:www.mywebsite.comとします。この一覧に記述するドメインの数は、20〜30以下に抑えてください。
関連するドメインのすべてのサブドメインをパターンマッチングの対象にするには、個々のドメイン名の先頭に*.を接頭辞として付けることで、ワイルドカードを指定します(ピリオド必須)。ドメイン名のパターンマッチングの基準になるのは、applinksエントリに含まれている最長の部分文字列です。たとえば、applinks:*.mywebsite.comとapplinks:*.users.mywebsite.comというエントリを指定した場合、emily.users.mywebsite.comドメインについては、長いほうの*.users.mywebsite.comエントリとのパターンマッチングが実行されます。*.mywebsite.comというエントリの場合、アスタリスクの後ろにピリオドがあるため、mywebsite.comに一致しているとは見なされないことに注意してください。*.mywebsite.comとmywebsite.comのどちらについてもパターンマッチングを有効にするには、applinksエントリをそれぞれ別に記述する必要があります。
[アプリ側] 2)ディープリンクをハンドリング
アプリでディープリンクを取得しドメインにより処理を切り分けます。
引用:
HandoffにUIApplicationDelegateメソッドを採用して(特にapplication:continueUserActivity:restorationHandler:)、アプリケーションでリンクを受信して適切に処理できるようにします。
実装コード例
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
let webpageURL = userActivity.webpageURL! // userActivity.webpageURLのurlを取得し、ドメイン判定を行い処理を切り分ける。サポートしていない場合はsafariへリダイレクト処理を入れるのが慣例
}return true
}
アプリをインストールしていない場合にStoreへ遷移するには
Universal Linksは直接Storeへの遷移はできないため、一旦、未インストール用のページをサーバで用意して、そちらに遷移し、そこのファイル内でStoreへ遷移させることが必要になります。
<a href=”itmss://itunes.apple.com/us/app/myapp/id[アプリID]?ls=1&mt=8″></a>
アプリIDにiTunesサイトのリンクのIDを入れると遷移します
参考
http://qiita.com/mono0926/items/2bf651246714f20df626
https://developer.apple.com/jp/documentation/General/Conceptual/AppSearch/UniversalLinks.html
はじめに
iOS/Androidで知っていた方がいいサイトをメモしておきます。
iOS
開発公式ページ(日本語)
https://developer.apple.com/jp/
公式ドキュメント(日本語)
https://developer.apple.com/jp/documentation/
WWDC
https://developer.apple.com/wwdc/
appleセキュリティアップデート情報
https://support.apple.com/en-us/HT201222
xcodeリリースノート
https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html
バージョンシェア情報
https://developer.apple.com/support/app-store/
Android
開発公式ページ
https://developer.android.com/index.html
マテリアルデザインガイドライン
https://material.io/guidelines/material-design/introduction.html
Google I/O
https://events.google.com/io/
APIレベル一覧
https://developer.android.com/guide/topics/manifest/uses-sdk-element.html?hl=ja
AndroidStudioのリリースノート
https://developer.android.com/studio/releases/index.html
バージョンシェア情報
https://developer.android.com/about/dashboards/index.html
はじめに
ターミナル起動時に画面に警告がでました。無視するで「y」で飛ばしてもいいのですが、毎回表示されるため消す方法をメモします。
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]?
原因
環境により違いがあると思いますが「compaudit」コマンドで何が影響か確認します。
$ compaudit
There are insecure directories:
/usr/local/share/zsh/site-functions/_carthage
/usr/local/share/zsh/site-functions/はzshでコマンド候補を文字するディレクトリです。
carthageはiosのパッケージマネージャで前回入れたものです。
対応:コマンドの警告を表示しないようにする
検索して調べると権限問題などで権限を755設定で解決するとありました。
http://qiita.com/ayihis@github/items/88f627b2566d6341a741
そもそもzshのワーニング表示を消したかったので、zshrcから警告を表示しない対応をします。
.zshrdファイルに次のシェルを追加します。(compinitの-uオプションを付けることで警告を無視します)
autoload -U compinit
compinit -u
これでターミナル起動時に警告が表示しなくなります。
はじめに
Carthage(カーセッジ)を使ったプロジェクトでswiftを2.2から3.0にコンバートした時に出たエラーを改善したメモを残します。
以下の2つのライブラリを取り込んでいたところエラーが表示しました
import Alamofire
import SwiftyJSON
原因
エラー内容
Module compiled with Swift 3.0 cannot be imported in Swift 3.0.2
swiftの3.0でコンパイルしたものを3.0.2でインポートすることはできないと言っているようです。
すでにコンパイルしているライブラリを持ってきていることが原因です。
解決
ソースコードを持ってきてローカル側でビルドすることで改善します。
carthageのupdateコマンドに–no-use-binariesオプションを追加することでバイナリを持ってこなくなります。
$ carthage update –no-use-binaries
最後にプロジェクトのクリーンを行いプロジェクトのビルドをすることで実行できました。
はじめに
1からMacにRails環境を構築する方法と概要についてメモします。
パッケージ管理ソフトはhomebrewを使用します。
Command Line Toolsインストール
Macで開発を行うためのコマンドラインツールをインストールします。
参考抜粋
——————————————————————————————————-
デベロッパ ポータルから直接、Xcode コマンド ライン ツールを .dmg ファイルとしてダウンロードすることができます。
Mac で https://developer.apple.com/downloads/index.action にアクセスします。
インストールの途中で Apple Developer としてログインするよう求められます。
[Downloads for Apple Developers]リストで、必要な[Command Line Tools]の項目を選択します。
——————————————————————————————————-
参考:
http://www.hulinks.co.jp/support/fortran/f_macosx018.html
Homebrewインストール
パッケージ管理ソフトのHomebrewをインストールします。Macにパッケージ類をインストールするためのソフトです。
インストール
$ ruby -e “$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)”
インストール確認(バージョンチェック)
$ brew -v
homebrewのバージョンが表示されれば成功です
rbendインストール
Rubyのバージョン管理に使用するrbenvをインストールします。
rubyのバージョンアップの切り替えをサポートするツールです。
rbend,ruby-buildインストール
$ brew install rbenv ruby-build
rbendのパスを設定します
echo ‘eval “$(rbenv init -)”‘ >> ~/.bash_profile
echo ‘export PATH=”$HOME/.rbenv/shims:$PATH”‘ >> ~/.bash_profile
source ~/.bash_profile
Rubyインストール
rbenvを使いrubyのインストール可能バージョンを確認します
$ rbenv install -l
上記よりインストールしたいrubyを選びインストールします
$ rbenv install (バージョン名)
例) 2.3.0のrubyをインストールする場合
$ rbenv install 2.3.0
※The Ruby openssl extension was not compiled. Missing the OpenSSL lib?エラーとなる場合
参考http://to-developer.com/blog/?p=1197
インストール確認をします
$ rbenv versions
関連ディレクトリの更新 ※しないといけない
$ rbenv rehash
参考
http://dqn.sakusakutto.jp/2014/02/rbenv_rehash_what_it_does.html
使用するrubyのバージョンを設定します
$ rbenv global 2.3.0
rubyのバージョンを確認します
$ ruby -v
ここでバージョンが2.3.0になっていれば成功です。
失敗した場合、PATHを確認します
$ which ruby
/usr/bin/rubyなどの場合はPATHが正しくありません
PATHの設定を行います
下記はbashの場合の.bash_profileにパス設定を行いますが、zshなどの場合はファイルを変更してください。
echo ‘export PATH=”$HOME/.rbenv/bin:$PATH”‘ >> ~/.bash_profile
echo ‘if which rbenv > /dev/null; then eval “$(rbenv init -)”; fi’ >> ~/.bash_profile
再度PATHを確認します
$ which ruby
/Users/*******/.rbenv/shims/rubyのようになっていれば成功です。
再度rubyのバージョンを確認します
$ ruby -v
ここでバージョンが2.3.0になっていれば成功です
Railsインストール
ruby標準のダウンロードツール(コマンド)gemを使いインストールします。
RDoc(Documentation from Ruby Source Files)をインストールします
$ gem install rdoc
※これをいれずにRailsをインストールすると「file ‘lib’ not found」がでます。
bundleライブラリを使ってrailsとその他gemをインストールする
Rails開発で使いそうなライブラリもgemでインストールしておきます。
gemをまとめて管理するためにbundleライブラリが用意されています。
gemfileにインストールするgemのリストを作るとインストールできます。
bundlerをインストールします
$ gem install bundler
gemfileの初期設定を行います。
bundle init
※カレントディレクトリにGemfileが作成されます。
Gemfileを次のように追加します。(よく利用するgemを仮にインストール設定します)
source “https://rubygems.org”
gem “rails”
gem “mysql”
gem “sqlite3″
gem “rake”
gem “uglifier”
gem “json”
gemのインストールを行います
$ bundle install –path vendor/bundle
Railsのバージョンを確認します
$ sudo rails -v
2016/12現在5.0.0.1が最新です
Railsプロジェクト作成
新規Railsプロジェクトの構成を作成します
$ sudo bundler exec rails new .
Gemfileを上書きするか聞かれますが、Yで上書きしてください。
Railsプロジェクト実行
Railsプロジェクトの直下でサーバを起動します
$ sudo bundler exec rails s
=> Booting Puma
=> Rails 5.0.0.1 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode…
* Version 3.6.2 (ruby 2.3.0-p0), codename: Sleepy Sunday Serenity
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
ブラウザでアクセスすることでRailsの初期画面が表示します。(起動を中止する場合はCtrl+Cです)
http://localhost:3000
はじめに
Carthage(カーセッジ)はライブラリ管理ツールです。プロジェクトの依存するライブラリまとめて管理することができます。
依存ライブラリのバージョンも指定できるので、ライブラリのバージョンがあがって動かなくなったなどがなくてよいです。railsあたりのBundlerのようなものです。
ライブラリツールはcocoapodsが定番でcarthageが別途作られてます。
ここら辺の違いなどはいろいろなサイトで紹介してました
http://qiita.com/nori0620/items/b81ae171f0e82b0c2d8a
Carthageリポジトリ:
https://github.com/Carthage/Carthage
Carthageを使ってライブラリをインストールする
http通信ライブラリのalamofireとjsonライブラリのswiftyjsonライブラリをプロジェクトに組み込みます。
https://github.com/Alamofire/Alamofire
https://github.com/SwiftyJSON/SwiftyJSON
Carthageのインストール
パッケージ管理のhomebrewを使います。
念のためbrewのアップデートをします
$ brew update
インストールします
$ brew install carthage
バージョン確認を確認します。2016/7/31現在は0.17.2でした。
$ carthage version
ライブラリの追加をする
Xcodeで新規プロジェクトを作成しターミナルでプロジェクト直下まで移動してください。
プロジェクト直下にcarthageの設定ファイルcartfileを作成します。
$ touch Cartfile
cartfileファイルにインストールするライブラリを追加します
github “SwiftyJSON/SwiftyJSON”
github “ishkawa/Alamofire”
cartfileファイルのインストールライブラリのビルドをします
$ carthage update –platform iOS (git)-[master]
*** Cloning SwiftyJSON
*** Fetching Alamofire
*** Checking out Alamofire at “3.4.1″
*** Checking out SwiftyJSON at “2.3.3″
*** xcodebuild output can be found in /var/folders/6q/1bzjyv810gbfrkhyy0sqrj280000gn/T/carthage-xcodebuild.0ZbSEg.log
*** Building scheme “Alamofire iOS” in Alamofire.xcworkspace
*** Building scheme “SwiftyJSON iOS” in SwiftyJSON.xcworkspace
※オプションに–platform iOSを入れることでwatch、osxプラットフォームのビルドを行わなくなります。iOSだけであれば不要です。
プロジェクトにライブラリを紐付ける
cocoapodsと違い、使用するライブラリを選んで取り込む作業が入ります。
ここまでの段階でプロジェクト配下にCarthage/Build/iOSディレクトリができています。
iOSディレクトリの中にAlamofire.frameworkファイルとSwiftyJSON.frameworkファイルがあり、このファイルをプロジェクトに取り込みます。
XcodeでプロジェクトのGeneralから「LinkedFrameworks and Libraries」の「+」ボタンを押します。
ダイアログが表示されるので、「Add Other…」ボタンから上記の2ファイルを選択して完了です。
ソースからコール
あとはソースないでimportするだけです。
import Alamofire
import SwiftyJSON
はじめに
ToolbarやTabLayoutなどに影の設定(elevation)が効いていなかったため対応をメモします。
※ロリポップより前はもともと影は標準ででません
CollapsingToolbarLayoutでtoolbarなどを括った場合に影が表示しない不具合があるようです。
対応策
stackoverに答えがありました。
参考:
http://stackoverflow.com/questions/32474073/android-design-library-toolbar-shadow
stackoverのとおりカスタムしたCollapsingToolbarLayoutを作成します。
※コンストラクタも必要です
public class ShadowCollapsingToolbarLayout extends CollapsingToolbarLayout { private AppBarLayout.OnOffsetChangedListener mOnOffsetChangedListener; public ShadowCollapsingToolbarLayout(final Context context) { super(context); } public ShadowCollapsingToolbarLayout(final Context context, final AttributeSet attrs) { super(context, attrs); } public ShadowCollapsingToolbarLayout(final Context context, final AttributeSet attrs, final int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); ViewParent parent = this.getParent(); if (parent instanceof AppBarLayout) { if (mOnOffsetChangedListener != null) ((AppBarLayout) parent).addOnOffsetChangedListener(mOnOffsetChangedListener); } } public void setOnOffsetChangeListener(AppBarLayout.OnOffsetChangedListener listener) { mOnOffsetChangedListener = listener; } }
レイアウトファイルでCollapsingToolbarLayoutをShadowCollapsingToolbarLayoutに差し替えます。あとはmCollapsingLayoutとした変数に以下のコードを実行します。
※CollapsingToolbarLayoutの中にあるAppBarLayoutにはelevationの数値設定をしてください。
mCollapsingLayout.setOnOffsetChangeListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int i) { ViewCompat.setElevation(appBarLayout, appBarLayout.getTargetElevation()); } });
これでうまく影が表示されるようになりました。
はじめに
githubにPRされたコードをレビューするときに、githubで直接みてレビューを行うことが多いですが、
コードをローカルに持ってきて実行などして確認したいことがあります。その場合のローカルにチェックアウトする方法をメモします。
参考:
https://help.github.com/articles/checking-out-pull-requests-locally/
PRをローカルでチェックアウト
PRしてまだマージしていないPRをローカルにチェックアウトします。
まずはPRの番号をgithub上で確認して以下のコードを実行します。
git fetch origin pull/番号/head:ブランチ名
※ブランチ名はなんでも大丈夫です。
そしてブランチをチェックアウトします
git checkout ブランチ名
これでローカルでコードを確認できます。
はじめに
標準出力(p,puts,printなど)の結果が正しいかどうかをチェックする方法をメモします。
ただ、標準出力はpublicメソッドで行わないので、テストするパターンは普通はないはずです。
テストツールはTest::Unitでやりますが、Rspecでも同様です。
方法
stringioを使うと標準出力、標準入力もテストできます。
stringioはruby標準のため、テストに限らず使えます。
考え方として、スタブを用意して差し替え、結果を取得するということです。
実装コード例)
require "stringio" require 'test/unit' class TestSample < Test::Unit::TestCase sub_test_case "Sub!" do def test_sub out = StringIO.new out.puts "hoge" assert_equal("hoge",out.string.chomp) end end end
stringioをrequireします。コードのとおり、StringIO.newのインスタンスでputsとすること部分をスタブとして結果をassertします。
はじめに
webviewでhttpサイトを表示しようとするとios9以降の場合、サイトが表示されません。
ios9よりATS(https通信)の設定がデフォルトでオンになっているため、表示できません。
前に同様の記事を書いたのに、ちょっとはまってしまいました。ちゃんとログをみないとだめですね。
ATSについてはこちら:
http://to-developer.com/blog/?p=2036
事象
実装コード例)
@IBOutlet weak var webView: UIWebView! let homeUrl = "http://yahoo.co.jp" // これがhttpsサイトならATSが有効状態で表示します。 override func viewDidLoad() { super.viewDidLoad() openUrl(homeUrl) } func openUrl(urlString: String){ let url = NSURL(string: urlString) let urlRequest = NSURLRequest(URL: url!) webView.loadRequest(urlRequest) }
httpサイトを表示しようとするとxcodeのログに次のログが出力されます。
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.
対応策
xcodeのログの通りplistファイルで一時的に回避することができます。
次のコードを追加することで回避できます。
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
はじめに
AndroidでAPI通信またはWebViewでページにアクセスする場合のSSLの必要性と対応についてメモします。
元々の考えでは、サイトの情報、apiにセキュアなデータが存在する場合はhttpsで、一般サイトなどはhttpを使っていました。
今後はスマホのセキュリティ的な考えのもと、httpsのみが推奨されてきています。
iOSはiOS9以降よりATSの有効化を推奨しておりデフォルトもオンになっています。
ATSについてはこちら:
http://to-developer.com/blog/?p=2036
Androidのセキュリティについて
Googleはセキュアな通信を推奨しています。ただAndroid上ではまだ推奨はしているとはおもいますが、特に設定上でデフォルトでセキュアな対応にはまだなっていないといった状態です。
AndroidにもあるiOSのATSなものについて
マニフェストの設定でusesCleartextTrafficがiosのATSと同等と思われます。デフォルトはhttpとしているため、まだhttpsを推奨としているわけではないようですが、いずれ推奨またはデフォルトは変わるのではないかと思います。
usesCleartextTraffic
アプリは、平文HTTPとして、クリアテキストのネットワークトラフィックを使用しようとするかどうかを示します。デフォルト値は「真」です。
属性は「偽」、プラットフォームコンポーネントに設定されている場合(例えば、HTTPおよびFTPスタックは、DownloadManager、MediaPlayerのは)クリアテキストトラフィックを使用するアプリケーションの要求を拒否します。サードパーティのライブラリを強く同様に、この設定を尊重することをお勧めします。クリアテキストトラフィックを回避するための主な理由は、機密性、真正性、および改ざんに対する保護の欠如である:ネットワーク攻撃者は、送信されたデータを盗聴し、また、検出されることなく、それを変更することができます。このフラグは、それが彼らに提供されるアクセスのレベルを指定したAndroidアプリケーションからすべてクリアテキストのトラフィックを防止することは不可能ですので、ベストエフォートベースで表彰されます。例えば、それは、そのトラフィックがクリアテキストであるかどうかを判断できないため、ソケットAPIはこのフラグを尊重するという期待がありません。ただし、アプリケーションからのほとんどのネットワークトラフィックがどちらかがApplicationInfo.flagsまたはNetworkSecurityPolicy.isCleartextTrafficPermittedからそれを読み取って、このフラグを尊重することができ、より高いレベルのネットワークスタック/コンポーネントによって処理されます()。
引用:
https://developer.android.com/guide/topics/manifest/application-element.html
webviewでhttps/http混在コンテンツについて
セキュリティのルールが変わり、Androidのロリポップ(5系)以上では、httpとhttpsの混在コンテンツのあるページをwebviewで表示しようとすると通信がブロックされるようになりました。httpsサイトの中でhttpの画像リソースを置いた場合などが混在コンテンツ扱いになります。
混在コンテンツをロリポップ以上でも許容するにはwebviewの設定でsetMixedContentModeでモードを「 MIXED_CONTENT_ALWAYS_ALLOW」に切り替えると、ブロックされなくなります。このデフォルトの設定がロリポップ(5系)以上で変更になってます。
5系以前はMIXED_CONTENT_ALWAYS_ALLOWでした。SEOとしても混在コンテンツはhttpsと評価されずに効果がでなくなるようです。
setMixedContentMode (Added in API level 21)
void setMixedContentMode (int mode)
Configures the WebView’s behavior when a secure origin attempts to load a resource from an insecure origin. By default, apps that target KITKAT or below default to MIXED_CONTENT_ALWAYS_ALLOW. Apps targeting LOLLIPOP default to MIXED_CONTENT_NEVER_ALLOW. The preferred and most secure mode of operation for the WebView is MIXED_CONTENT_NEVER_ALLOW and use of MIXED_CONTENT_ALWAYS_ALLOW is strongly discouraged.
引用:
https://developer.android.com/reference/android/webkit/WebSettings.html
httpsにする必要性
セキュアにする理由
クリアテキストトラフィックを回避するための主な理由は、機密性、真正性、および改ざんに対する保護の欠如である:ネットワーク攻撃者は、送信されたデータを盗聴し、また、検出されることなく、それを変更することができます。
httpsによるSEOの評価について(HTTPSをランキングシグナルに利用する)
https化対応にするメリットはSEOでクローラーの評価が違うことがあります。
セキュリティは Google の最優先事項です。Google は、デフォルトで強力な HTTPS 暗号化を導入するなど、業界でも最先端のセキュリティを Google サービスに導入することに力を注いでいます。これにより、たとえば Google 検索、Gmail、Google ドライブを使用しているユーザーは自動的に、Google に安全に接続することができます。
Google は、Google のサービスだけにとどまらず、より広い範囲でインターネットを安全に利用できるように取り組んでいます。そこで大きな割合を占めているのは、ユーザーが Google から安全なサイトにアクセスできるようにすることです。たとえば、Google ではウェブマスター向けにハッキングの対策や修正方法について詳しい情報を提供するサイトを作成しました。
Google ではさらにもう一歩踏み込んで、数か月前の Google I/O では、「HTTPS everywhere」をウェブで提唱しました。
また、ますます多くのウェブマスターが HTTPS(HTTP over TLS / Transport Layer Security)を彼らのサイトに導入するようになってきています。これはとても心強いことです。
こうした理由から、Google では過去数か月にわたり、Google のランキング アルゴリズムでのシグナルとして、暗号化された安全な接続をサイトで使用しているかを考慮に入れたテストを実施してきました。この実験ではよい結果が得られているため、ユーザーがもっと安全にサイトを閲覧できるよう、すべてのサイト所有者の皆様に HTTP から HTTPS への切り替えをおすすめしたいと考えています。Google は、みなさんがより簡単に TLS を導入し、よくある失敗を避けられるように、今後数週間のうちに詳細なベスト プラクティスを公開する予定です(Update: こちらのヘルプ記事内で公開しました)。開始にあたって、以下の基本的なヒントもご確認ください。
必要な証明書タイプを決定します: シングル、マルチ ドメイン、ワイルド カード
2048 bit の証明書を使用します
同じ安全なドメイン上にあるリソースには相対 URL を使用します
他のすべてのドメインにはプロトコル相対 URL を使用します
サイトのアドレスの変更方法について詳しくは、サイト移転に関するヘルプ記事をご覧ください
robots.txt を使用して HTTPS サイトへのクロールをブロックしないでください
可能な限り検索エンジンがページをインデックス登録できるようにします。Noindex メタタグの使用は避けます。
サイトが既に HTTPS で配信されている場合は、Qualys Lab ツールを使用してウェブサイトのセキュリティ レベルと設定をテストできます。TLS とサイト パフォーマンスについて不安がある場合は、「Is TLS fast yet?」(英語)をご覧ください。また、ご質問やご不明な点がある場合は、ウェブマスター ヘルプ フォーラムでお尋ねください。
このランキングの変更は、グローバルでクエリの 1% 未満にしか影響しませんが、これから長い期間をかけて強化していきます。全体的に見ると、このシグナルは良質なコンテンツであるといった、その他のシグナルほどウェイトは大きくありません。HTTPS は、優れたユーザー エクスペリエンスを生み出す多くの要素のうちの 1 つです。
今後、より多くのウェブサイトで HTTPS が使用されることを期待しています。ウェブの安全性をさらに強化しましょう。
参考:
http://googlewebmastercentral-ja.blogspot.jp/
発表当時2014/8/7は
「このランキングの変更は、グローバルでクエリの 1% 未満にしか影響しませんが、これから長い期間をかけて強化していきます。全体的に見ると、このシグナルは良質なコンテンツであるといった、その他のシグナルほどウェイトは大きくありません。HTTPS は、優れたユーザー エクスペリエンスを生み出す多くの要素のうちの 1 つです。」
の通りのため、ほとんどhttps化によるSEOの効果はなかったと思います。
いまはどうでしょうか。
Indexing HTTPS pages by default
Thursday, December 17, 2015
At Google, user security has always been a top priority. Over the years, we’ve worked hard to promote a more secure web and to provide a better browsing experience for users. Gmail, Google search, and YouTube have had secure connections for some time, and we also started giving a slight ranking boost to HTTPS URLs in search results last year. Browsing the web should be a private experience between the user and the website, and must not be subject to eavesdropping, man-in-the-middle attacks, or data modification. This is why we’ve been strongly promoting HTTPS everywhere.
As a natural continuation of this, today we’d like to announce that we’re adjusting our indexing system to look for more HTTPS pages. Specifically, we’ll start crawling HTTPS equivalents of HTTP pages, even when the former are not linked to from any page. When two URLs from the same domain appear to have the same content but are served over different protocol schemes, we’ll typically choose to index the HTTPS URL if:
It doesn’t contain insecure dependencies.
It isn’t blocked from crawling by robots.txt.
It doesn’t redirect users to or through an insecure HTTP page.
It doesn’t have a rel=”canonical” link to the HTTP page.
It doesn’t contain a noindex robots meta tag.
It doesn’t have on-host outlinks to HTTP URLs.
The sitemaps lists the HTTPS URL, or doesn’t list the HTTP version of the URL
The server has a valid TLS certificate.
Although our systems prefer the HTTPS version by default, you can also make this clearer for other search engines by redirecting your HTTP site to your HTTPS version and by implementing the HSTS header on your server.
We’re excited about taking another step forward in making the web more secure. By showing users HTTPS pages in our search results, we’re hoping to decrease the risk for users to browse a website over an insecure connection and making themselves vulnerable to content injection attacks. As usual, if you have any questions or comments, please let us know in the comments section below or in our webmaster help forums.
https://webmasters.googleblog.com/
クローラーのindexはhttpsを優先するとあります。
効果はわかりませんが、だいぶ優先してくれるようです。
まとめ
AppleもGoogleもセキュアな通信を基本推奨しているので、今後はサーバ側で対応しアプリも基本Strictな設定(https通信のみ)にすることが必要となるようです。
現行ではiOSであればATSを無効にすることやAndroidはデフォルト無効のため、急ぐ必要はまだないとはおもうのですが。
参考:
https://koz.io/android-m-and-the-war-on-cleartext-traffic/
https://developer.android.com/guide/topics/manifest/application-element.html
はじめに
gitのあるコミットとあるコミットの差分ファイルのみ取得するやり方をメモしておきます。
差分ファイル取得
差分ファイル取得のgitコマンドは次の通りです。
git diff [oldコミット] [newコミット] --name-only | git checkout-index --prefix=[出力先] --stdin
一つ前のコミットの差分ファイルを取得するサンプルは次の通りです。※出力先は一つ上のディレクトリのarchiveディレクトリにしてます
git diff head^ head --name-only | git checkout-index --prefix=../archive/ --stdin
はじめに
ギャラリー・カメラの選択した画像をonActivityResultで取得する場合に以前は「content://media/external/images/media/」形式で
URLが取得できていましたが、「storage/sdcard0/」形式のファイル取得になりました。SDKのバージョン上げたからかな?変わったのかな?調べてません。
そのためcursolがnullになりエラーに陥ったので対応策をメモしておきます。
対応策
「content://media/external/images/media/」形式
「storage/sdcard0/」形式
どちらの場合も対応できるようにコードを分岐しました。
public static final String[] PROJECTION = { Images.ImageColumns._ID, // 0 Images.ImageColumns.TITLE, // 1 Images.ImageColumns.MIME_TYPE, // 2 Images.ImageColumns.LATITUDE, // 3 Images.ImageColumns.LONGITUDE, // 4 Images.ImageColumns.DATE_TAKEN, // 5 Images.ImageColumns.DATE_ADDED, // 6 Images.ImageColumns.DATE_MODIFIED, // 7 Images.ImageColumns.DATA, // 8 Images.ImageColumns.ORIENTATION, // 9 Images.ImageColumns.BUCKET_ID, // 10 Images.ImageColumns.SIZE, // 11 Images. ImageColumns.BUCKET_DISPLAY_NAME, // 12 }; public void onActivityResult(int requestCode, int resultCode, Intent data) { Uri uri = data.getData(); Cursor cursor = null; if (ContentResolver.SCHEME_CONTENT.equals( uri.getScheme()) ){ // content://media/external/images/media/形式 ContentResolver cr = getContentResolver(); String[] columns = {MediaStore.Images.Media.DATA }; cursor = cr.query(mData.getData(), columns, null, null, null); } else { // storage/sdcard0/形式 ※HDのディレクトリ構成のまま cursor = getContentResolver().query( Images.Media.EXTERNAL_CONTENT_URI, PROJECTION, Images.ImageColumns.DATA + " LIKE '%" + mData.getData().toString() + "%'", null, null ); } String fileName = cursor.getString(c.getColumnIndex(Images.Media.DATA)); }
はじめに
AndroidStudioでビルドで「Duplicate files copied in APK META-INF/LICENSE 」エラーがでました。
Duplicateなのでライブラリ間でファイル名が同名のがあるようです。
対応策
build.gradleファイルでexclude指定でファイルを除外できます。
他に同様のDuplicate files copiedエラーが出た場合は対象のファイルを除外に追加するといいと思います。
android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/NOTICE' } }
これでビルドが出来るようになりました
はじめに
AndroidStudio作成のgradle環境のプロジェクトをコマンド実行します。
gradleコマンドは全環境に依存しているため、プロジェクト毎に関連性を持つGradleをラップしたgradlewコマンドを使います。
前回作成のプロジェクトをコマンド実行してみます
[Android]Gradleファイルで環境ごとに処理を切り分け(APK名・Keystore設定など)
プロジェクトは以下
https://github.com/y-matsumoto/template-project
タスク確認
プロジェクト直下にgradlew.batができてます。こちらを使います。
まずはプロジェクト直下に移動して以下のコマンドを実行し、タスク一覧を確認します
$ gradlew tasks Parallel execution with configuration on demand is an incubating feature. :tasks ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Android tasks ------------- androidDependencies - Displays the Android dependencies of the project. signingReport - Displays the signing info for each variant. sourceSets - Prints out all the source sets defined in this project. Build tasks ----------- assemble - Assembles all variants of all applications and secondary packages. assembleAndroidTest - Assembles all the Test applications. assembleDebug - Assembles all Debug builds. assembleDevelop - Assembles all Develop builds. assembleProduct - Assembles all Product builds. assembleRelease - Assembles all Release builds. assembleStaging - Assembles all Staging builds. build - Assembles and tests this project. buildDependents - Assembles and tests this project and all projects that depend on it. buildNeeded - Assembles and tests this project and all projects it depends on. clean - Deletes the build directory. compileDevelopDebugAndroidTestSources compileDevelopDebugSources compileDevelopDebugUnitTestSources compileDevelopReleaseSources compileDevelopReleaseUnitTestSources compileProductDebugAndroidTestSources compileProductDebugSources compileProductDebugUnitTestSources compileProductReleaseSources compileProductReleaseUnitTestSources compileStagingDebugAndroidTestSources compileStagingDebugSources compileStagingDebugUnitTestSources compileStagingReleaseSources compileStagingReleaseUnitTestSources mockableAndroidJar - Creates a version of android.jar that's suitable for unit tests. Build Setup tasks ----------------- init - Initializes a new Gradle build. [incubating] wrapper - Generates Gradle wrapper files. [incubating] Help tasks ---------- components - Displays the components produced by root project 'template-project'. [incubating] dependencies - Displays all dependencies declared in root project 'template-project'. dependencyInsight - Displays the insight into a specific dependency in root project 'template-project'. help - Displays a help message. model - Displays the configuration model of root project 'template-project'. [incubating] projects - Displays the sub-projects of root project 'template-project'. properties - Displays the properties of root project 'template-project'. tasks - Displays the tasks runnable from root project 'template-project' (some of the displayed tasks may belong to subprojects). Install tasks ------------- installDevelopDebug - Installs the DebugDevelop build. installDevelopDebugAndroidTest - Installs the android (on device) tests for the DevelopDebug build. installProductDebug - Installs the DebugProduct build. installProductDebugAndroidTest - Installs the android (on device) tests for the ProductDebug build. installStagingDebug - Installs the DebugStaging build. installStagingDebugAndroidTest - Installs the android (on device) tests for the StagingDebug build. uninstallAll - Uninstall all applications. uninstallDevelopDebug - Uninstalls the DebugDevelop build. uninstallDevelopDebugAndroidTest - Uninstalls the android (on device) tests for the DevelopDebug build. uninstallDevelopRelease - Uninstalls the ReleaseDevelop build. uninstallProductDebug - Uninstalls the DebugProduct build. uninstallProductDebugAndroidTest - Uninstalls the android (on device) tests for the ProductDebug build. uninstallProductRelease - Uninstalls the ReleaseProduct build. uninstallStagingDebug - Uninstalls the DebugStaging build. uninstallStagingDebugAndroidTest - Uninstalls the android (on device) tests for the StagingDebug build. uninstallStagingRelease - Uninstalls the ReleaseStaging build. Verification tasks ------------------ check - Runs all checks. connectedAndroidTest - Installs and runs instrumentation tests for all flavors on connected devices. connectedCheck - Runs all device checks on currently connected devices. connectedDevelopDebugAndroidTest - Installs and runs the tests for developDebug on connected devices. connectedProductDebugAndroidTest - Installs and runs the tests for productDebug on connected devices. connectedStagingDebugAndroidTest - Installs and runs the tests for stagingDebug on connected devices. deviceAndroidTest - Installs and runs instrumentation tests using all Device Providers. deviceCheck - Runs all device checks using Device Providers and Test Servers. lint - Runs lint on all variants. lintDevelopDebug - Runs lint on the DevelopDebug build. lintDevelopRelease - Runs lint on the DevelopRelease build. lintProductDebug - Runs lint on the ProductDebug build. lintProductRelease - Runs lint on the ProductRelease build. lintStagingDebug - Runs lint on the StagingDebug build. lintStagingRelease - Runs lint on the StagingRelease build. test - Run unit tests for all variants. testDevelopDebugUnitTest - Run unit tests for the developDebug build. testDevelopReleaseUnitTest - Run unit tests for the developRelease build. testProductDebugUnitTest - Run unit tests for the productDebug build. testProductReleaseUnitTest - Run unit tests for the productRelease build. testStagingDebugUnitTest - Run unit tests for the stagingDebug build. testStagingReleaseUnitTest - Run unit tests for the stagingRelease build. Other tasks ----------- clean jarDevelopDebugClasses jarDevelopReleaseClasses jarProductDebugClasses jarProductReleaseClasses jarStagingDebugClasses jarStagingReleaseClasses lintVitalDevelopRelease - Runs lint on just the fatal issues in the DevelopRelease build. lintVitalProductRelease - Runs lint on just the fatal issues in the ProductRelease build. lintVitalStagingRelease - Runs lint on just the fatal issues in the StagingRelease build. To see all tasks and more detail, run gradlew tasks --all To see more detail about a task, run gradlew help --task <task> BUILD SUCCESSFUL Total time: 4.033 secs
Androidプロジェクトのビルド
タスクにより端末にインストールや、ビルド、APKファイル作成を指定環境ごとに作成します。
試しにassembleReleaseタスクを実行します
$ gradlew assembleDebug Parallel execution with configuration on demand is an incubating feature. :app:preBuild UP-TO-DATE :app:preDevelopDebugBuild UP-TO-DATE :app:checkDevelopDebugManifest :app:preDevelopReleaseBuild UP-TO-DATE :app:preProductDebugBuild UP-TO-DATE :app:preProductReleaseBuild UP-TO-DATE :app:preStagingDebugBuild UP-TO-DATE :app:preStagingReleaseBuild UP-TO-DATE :app:prepareComAndroidSupportAppcompatV72221Library UP-TO-DATE :app:prepareComAndroidSupportDesign2221Library UP-TO-DATE :app:prepareComAndroidSupportSupportV42221Library UP-TO-DATE :app:prepareDevelopDebugDependencies :app:compileDevelopDebugAidl UP-TO-DATE :app:compileDevelopDebugRenderscript UP-TO-DATE :app:generateDevelopDebugBuildConfig UP-TO-DATE :app:generateDevelopDebugAssets UP-TO-DATE :app:mergeDevelopDebugAssets UP-TO-DATE :app:generateDevelopDebugResValues UP-TO-DATE :app:generateDevelopDebugResources UP-TO-DATE :app:mergeDevelopDebugResources UP-TO-DATE :app:processDevelopDebugManifest UP-TO-DATE :app:processDevelopDebugResources UP-TO-DATE :app:generateDevelopDebugSources UP-TO-DATE :app:processDevelopDebugJavaRes UP-TO-DATE :app:compileDevelopDebugJavaWithJavac UP-TO-DATE :app:compileDevelopDebugNdk UP-TO-DATE :app:compileDevelopDebugSources UP-TO-DATE :app:preDexDevelopDebug UP-TO-DATE :app:dexDevelopDebug UP-TO-DATE :app:validateDebugSigning :app:packageDevelopDebug :app:zipalignDevelopDebug :app:assembleDevelopDebug :app:checkProductDebugManifest :app:prepareProductDebugDependencies :app:compileProductDebugAidl UP-TO-DATE :app:compileProductDebugRenderscript UP-TO-DATE :app:generateProductDebugBuildConfig UP-TO-DATE :app:generateProductDebugAssets UP-TO-DATE :app:mergeProductDebugAssets UP-TO-DATE :app:generateProductDebugResValues UP-TO-DATE :app:generateProductDebugResources UP-TO-DATE :app:mergeProductDebugResources UP-TO-DATE :app:processProductDebugManifest UP-TO-DATE :app:processProductDebugResources UP-TO-DATE :app:generateProductDebugSources UP-TO-DATE :app:processProductDebugJavaRes UP-TO-DATE :app:compileProductDebugJavaWithJavac UP-TO-DATE :app:compileProductDebugNdk UP-TO-DATE :app:compileProductDebugSources UP-TO-DATE :app:preDexProductDebug UP-TO-DATE :app:dexProductDebug UP-TO-DATE :app:packageProductDebug :app:zipalignProductDebug :app:assembleProductDebug :app:checkStagingDebugManifest :app:prepareStagingDebugDependencies :app:compileStagingDebugAidl UP-TO-DATE :app:compileStagingDebugRenderscript UP-TO-DATE :app:generateStagingDebugBuildConfig UP-TO-DATE :app:generateStagingDebugAssets UP-TO-DATE :app:mergeStagingDebugAssets UP-TO-DATE :app:generateStagingDebugResValues UP-TO-DATE :app:generateStagingDebugResources UP-TO-DATE :app:mergeStagingDebugResources UP-TO-DATE :app:processStagingDebugManifest UP-TO-DATE :app:processStagingDebugResources UP-TO-DATE :app:generateStagingDebugSources UP-TO-DATE :app:processStagingDebugJavaRes UP-TO-DATE :app:compileStagingDebugJavaWithJavac UP-TO-DATE :app:compileStagingDebugNdk UP-TO-DATE :app:compileStagingDebugSources UP-TO-DATE :app:preDexStagingDebug UP-TO-DATE :app:dexStagingDebug UP-TO-DATE :app:packageStagingDebug :app:zipalignStagingDebug :app:assembleStagingDebug :app:assembleDebug BUILD SUCCESSFUL Total time: 5.978 secs
BUILD SUCCESSFULで成功です。
template-project\app\build\outputs\apkディレクトリにdebugモードで各環境(develop,staging,product)でapkファイルが作成されます。
環境毎に実行する場合はassembleDevelop,assembleStaging,assembleProductタスクを実行してください。debug,releaseでファイルが作成されます。
ant,mavenより簡単で早いですね。
coffee-break
Don't write code that useless.
1日5杯はコーヒー、カフェオレ飲みます。狭心症のため安静にします☆松本 雄貴
Kotlinでサービスリリース目指す!
iOSでチャットアプリ作成中。自然言語解析LSIを習得中
Mac / Android・iOS / Rails / Oracle
2017年 Lpic L2取得
2012年 Android技術者資格取得
2010年 OracleMasterGold10g取得
2008年 CCNAQiitaもたまに投稿
https://qiita.com/y-matsumoto東京近郊で常駐開発探してる方はこちらよりご連絡ください
SES企業でパートナー会社を探している企業様はこちらよりご連絡ください
スプリットカメラ iOS / Android
音声認識で聞いた日付から曜日当てアプリ Android
ソーシャルタイマー Android
カテゴリー
- ActiveRecord (2)
- Android (52)
- AndroidStudio (10)
- Ansible (1)
- AWS (1)
- Bash (18)
- Blog (7)
- BootStrap (1)
- CentOS (16)
- Chef (1)
- css (2)
- Eclipse (5)
- error (1)
- Facebook (2)
- Firebase (1)
- FuelPHP (16)
- Git (22)
- GitHub (3)
- Gradle (2)
- GraphAPI (1)
- Grunt (1)
- heroku (2)
- illustrator (1)
- iOS (17)
- Java (4)
- Jenkins (1)
- jQuery (3)
- Kotlin (2)
- Mac (22)
- nginx (1)
- Node.js (3)
- peco (1)
- php (5)
- Python (1)
- Rails (16)
- Ruby (11)
- shell (1)
- SNS (1)
- Swift (2)
- tmux (2)
- Vagrant (6)
- Vim (6)
- windows (2)
- WordPress (3)
- zsh (4)
- フリーランス (1)
- ライブラリ (1)
- 勉強会 (2)
- 宣伝 (1)
- 未分類 (2)
最近の投稿
- [MAC]HighSierraでgitプッシュエラー「Unable to negotiate with xxx.xxx.xxx.xxx port xx: no matching cipher found. Their offer: aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se fatal: Could not read from remote repository.」
- [iOS]iOS11からFacebook,Twitter連携(シェアなど)廃止の対応方法
- [iOS]速報2017AppleSpecialEventのiOS11、iPhone8など発表内容について
- [iOS][Firebase]The default Firebase app has not yet been configured. Add `[FIRApp configure];
- [iOS]2017年9月リリースのiOS11で開発者が対応するべきこと
- 今人気の現金化サービスCASH(キャッシュ)を使ったレビュー
- [Pandoc][Mac]pandocでmarkdownからwordファイル作成
- [Android]映画サマーウォーズの聞いた日付(誕生日)から曜日当てをアプリ音声認識で簡単に実現
- [Android]起動しているActivityを取得するadb shell コマンド
- [Android][Kotlin]kotlin学習で参考になるサイト一覧
2024年3月 月 火 水 木 金 土 日 « 5月 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 アーカイブ
- 2018年5月
- 2017年9月
- 2017年8月
- 2017年7月
- 2017年6月
- 2017年5月
- 2017年2月
- 2017年1月
- 2016年12月
- 2016年7月
- 2016年6月
- 2016年1月
- 2015年12月
- 2015年11月
- 2015年10月
- 2015年9月
- 2015年8月
- 2015年7月
- 2015年6月
- 2015年5月
- 2015年4月
- 2015年3月
- 2015年2月
- 2015年1月
- 2014年12月
- 2014年11月
- 2014年6月
- 2014年5月
- 2014年4月
- 2014年3月
- 2014年2月
- 2014年1月
- 2013年12月
- 2013年11月
- 2013年9月
- 2013年8月
- 2013年7月
- 2013年6月
- 2013年5月
- 2013年4月
- 2013年3月
- 2013年2月
- 2013年1月
- 2012年12月
- 2012年10月
- 2012年5月
- 2010年6月
エントリ