素振り用iOSプロジェクト fcm編
前回
素振り用iOSプロジェクト fastlane match編 - kz-kazuki’s blog
今回のゴール
firebase cloud messaging(以下fcm)を使ってpush通知を送ることができる
firebaseのドキュメント読んでポチポチすれば終わるが...
firebase
新しくプロジェクトを作成する
iOSボタンを押すと進むので指示通りに作業
現時点ではまだPod推奨なので、*.xcworkspace から起動することになる
fastlaneでapns用証明書を作成する
fastlane/Fastfileにコマンドを追加 (bundle_idをAppFileに記述してるので不要
... desc "create develop apns cert." lane :create_apns_develop do pem( force: true, development: true, save_private_key: true ) end
コマンドを実行する
... [16:51:12]: Creating a new push certificate for app 'org.assaulter.base'. Private key, p12 certificate, PEMが保存されている旨が表示 ...
.p12をfirebaseにアップロード
(p8がfastlaneで作れるか調べてない。できるならそっちのほうが楽
firebase console > プロジェクトを設定 > クラウドメッセージング で、開発用APNs証明書としてアップロードする
push notificationが使えるようにする
xcode > Signing & Capabilities で Push Notificationss を追加する
以下のコマンドを追加し実行
desc "renew develop provisioning profile." lane :force_develop do match(type: "development", force: true) end
$ bundle exec fastlane force_develop
dev centerでidentifierが更新されていることを確認する
push許諾とfcm連携
一旦AppDelegateに実装を追加する
import UIKit import Firebase import FirebaseMessaging @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. FirebaseApp.configure() Messaging.messaging().delegate = self UNUserNotificationCenter.current().delegate = self registerRemoteNotification() return true } // MARK: UISceneSession Lifecycle func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { // Called when a new scene session is being created. // Use this method to select a configuration to create the new scene with. return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { // Called when the user discards a scene session. // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. // Use this method to release any resources that were specific to the discarded scenes, as they will not return. } } // MARK: - private private extension AppDelegate { /// テスト用なのでcompletionは特に何もしない func registerRemoteNotification() { let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: { granted, error in if granted { DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } }) } } // MARK: - UNUserNotificationCenterDelegate extension AppDelegate: UNUserNotificationCenterDelegate { func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString: String = deviceToken.map { String(format: "%.2hhx", $0) }.joined() debugPrint("deviceTokenString \(deviceTokenString)") } func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) { debugPrint("リモート通知の設定は拒否されました") } func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let userInfo = notification.request.content.userInfo debugPrint("userInfo: \(userInfo)") completionHandler([.alert, .sound]) } } // MARK: - MessagingDelegate extension AppDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { debugPrint("fcmToken: \(fcmToken)") // TODO: If necessary send token to application server. // Note: This callback is fired at each app startup and whenever a new token is generated. } }
実機でアプリを起動し、許諾を承認するとfcmTokenがログに出る
fcm http api v1を使って動作確認
firebase console > プロジェクトの設定 > サービスアカウント > Firebase Admin SDK > 「新しい秘密鍵を生成」を押す
落ちてきたjsonファイルは保管しておく
認証とリクエストを行うrubyのスクリプト
雑に
# frozen_string_literal: true source "https://rubygems.org" gem "google-api-client" gem "faraday" gem "googleauth"
require 'bundler' Bundler.require require 'json' # Config file_path = "service account key file path" project_id = "Your firebase project id" token = "fcmToken from app." # get access token authorizer = Google::Auth::ServiceAccountCredentials.make_creds( json_key_io: File.open(file_path), scope: 'https://www.googleapis.com/auth/firebase.messaging' ) access_token = authorizer.fetch_access_token! access_key = "#{access_token['token_type']} #{access_token['access_token']}" # request uri = URI.parse("https://fcm.googleapis.com/v1/projects/#{project_id}/messages:send") https = Net::HTTP.new(uri.host, uri.port) https.use_ssl = true req = Net::HTTP::Post.new(uri) req['Content-Type'] = 'application/json' req['Authorization'] = access_key req.body = { message: { token: token, notification: { title: 'test push notification', body: 'notification message from fcm.' } } }.to_json res = https.request(req) p res
configの部分を埋めて実行するとpushが飛ぶのを確認できる
素振り用iOSプロジェクト fastlane match編
概要
fastlane matchのドキュメントに書いてあることをかいつまんで実行
環境
Xcode 11.5
手順
Xcode
fastlane準備
参考:https://qiita.com/shumatsukishu/items/f398a449a07b0bc15e0f
- Gemfile追加 & Bundle install
fastlane初期化
バージョン:2.154.0
$ bundle exec fastlane init
- 選択肢が出るのでManual setupを選ぶ
- /fastlane が作成されることを確認
DevCenterに登録
$ bundle exec fastlane produce -a org.assaulter.base -i
- IDとMFA聞かれるのでよしなに
- DevCenterに作成されるのを確認
- -iを指定しているので、AppStoreConnectには作成されない
- fastlane/Appfileのapp_identifierとapple_idを埋めておく
実機確認用証明書管理
予めプライベートリポジトリを用意しておく
複数プロジェクトを単一リポジトリで扱うことも可能
$ bundle exec fastlane match init
- Gitを指定し、urlを入れる(プライベートリポジトリ)
- MATCH_PASSWORDを設定しておく
- 今回はenvrcを使った
$ bundle exec fastlane match development
- Dev centerでcertificateとprovisioning profileができているのを確認
- 登録済みの実機で動作確認
5月投資振り返り
マザーズ指数だけ見ると完全にコロナなんてなかったことになってますが、これからどうなるんでしょうか
売買履歴振り返り
IBJ
5/1 -> 5/12
5/18 -> 5/21
決算だったんで一旦利確しました。
もうすぐゴールデンクロスな気がするのでまたINしようかなと。
BASE
5/19 売却 S高マイナス10%のところに逆指値置いてたら売れちゃいました。 3,000円割れないですねー
イー・ギャランティ
5/18 購入 短期移動平均線近くまで下げたので購入。割高感はあるのであんまり長くホールドはしないかも。
ヤマハ発動機
5/27 -> 5/28 マザーズ -> 東証一部の流れかなと思い割安感があったので購入。 やっぱり決算が怖くて利確。無配になってしまいましたがどうなりますかね。
ほしい銘柄
米株
- BYND
- RPAY
- NET
- NYSE
ITエンジニアが使うサービスの株買っておけば良いんじゃね理論ですがどれも割高感が。。。
再度暴落が来るのであればQQQに入れて気絶で良いかも。。。
日本株
- 凸版印刷
- Shofoo!やってるのに気づかなかった。色々やってるんですね。
- DMS
- 暴落前のチャートが良くて業界首位で割安感っていう軽い考え
まとめ
新興国デフォルトとか米中関係とかで暴落来るの待っててだいぶ現金の割合が高いんですが、そうならなかったら適当にETFに突っ込んでまた日常に戻ろうかなと思っています。
4月投資振り返り
COVID-19の影響で完全リモートワークになり、通勤時間が浮いたので、それを投資の勉強?などにあてています。
今まではつみたてNISA米株毎日積立しかやってなかったのですが、恐る恐る個別も買いました。2番底警戒しながらなので、保有現金のうち20%くらいしか突っ込めてなくて悔しい思いをしています。
売買履歴振り返り
三菱UFJ(購入: 3/18, 売却: 3/31)
4年ぶりくらいだったので、肩慣らしに売買。
日経平均の一番底が3/19だったので、タイミングとしてはほぼ完璧だけど銘柄それじゃないだろっていう。
BASE(購入: 3/31)
リアル店舗→ECの流れが強いのでは?ということで割と本命なのでホールド中。shopifyはすんげー上がりましたね。
エアトリ(購入: 4/17, 売却: 4/20)
出遅れを探してて購入したけどやっぱり影響が読めないってことですぐ利確。安い気はするんですけど別にそんなリスク取らなくても良いかな?
ウィルプラスHD(購入: 4/23)
増収増益・小型株・低PERで引っかかったので保有。5/8短信出ましたが一旦大丈夫かな。。。
トレードも含めて今の所勝率100%という異常事態なのですが、全然お金入れてないのでもったいないことをしたなぁと。
今後の方針
個別株は長期ホールドで大化けを狙いたいと思っています。
一応ITエンジニアなので、IT系小型株を集めていきたいんですが、早速Fastly買おうとしたら5/7決算出て+40%を見送るという事態になりました。先行き不安です。
2019年を振り返る
できごと
転職した
- iOSの開発が一旦ストップしそう
- 複数回誘われた
ということでホイホイつられて同じビルの別の階の会社に6月頃転職。
転職を決めてから辞めるまでの間はリソースが足りないこともあり(人員計画がかなりアレだなぁと思う...)サーバーサイドの仕事を結構ゴリゴリやりつつiOSアプリのメンテみたいなことをやってて、これはこれで楽しかったので微妙に後悔したりしなかったり。
僕にしては珍しく、同時期入社の人達と仲良くしてもらってて、人間関係はかなり良好でした(まあ、ほとんど別のところに行っちゃったんですが。またどこかで一緒に仕事したいなと思ってますので今後ともよろしくおねがいします。
新しい職場
途中からマネージャーが加わってすごく良くなった。加わる前は正直かなり酷くてどうしたもんかと思いつつも、歴史あるプロダクトに機能を付け加えたりなんたりするのに必死だったので一瞬で半年が終わってしまった。
来年からまた組織変わるっぽくて、せっかくうまくドライブするようになってきたのになーという感情がある。
転職について
複数回やると慣れちゃって完全に抵抗がなくなるので、それはそれで良くないなぁと思ったり。
デメリットは明確で、とにかく手続き関係がダルい。
特に企業型確定拠出年金制度があるところから無いところに移動する際にiDeCoに切り替えるんですが、ブランクが長くて機会損失半端なさすぎて呆れました。
職場の立地など
高速エレベーターがあるような高層ビルに対してかなりネガティブになってしまった。
もともと気圧の変化に弱いので、今後職場を選ぶときはオフィスビルも考慮材料になりそう。。。
キャリアなど
来期から徐々に人も見るようになっていくらしいのでまずはそれをやってから考えようと思ってます。
サラリーマンの給与の期待値になるとやっぱりエンジニアリング + ナニカというのが王道なんでしょうか。
労働について
就職してから今まで多分2週間以上の長い休みというものを取ったことがなく、ちょっと疲れてきたのかもしれない!
どうもここ1年くらいはネガティブなことを考えがちです。具体的に言うと目標設定から逃避したい。
お金関係
転職などあり自分で売買する精神的余裕がなかったので脳死投資
そろそろ株全ツッパなポートフォリオを見直すときかなと思うんですが、どうでしょうか?
積立NISA
SBIで営業日毎に以下の銘柄を300円ずつ購入。
- 大和-iFree S&P500インデックス
- 楽天-楽天・全米株式インデックス・ファンド
- ニッセイ-<購入・換金手数料なし>ニッセイ外国株式インデックスファン
- ニッセイ-ニッセイ日経225インデックスファンド
上から順にパフォーマンスが良いです。どれも10%強プラスになってる。
iDeCo
- 楽天・全米株式インデックス・ファンド
9月から開始したのに +8%強で完全にバブル
てか積立NISAと同じ銘柄w
LINEワンコイン投資
- 週2,000円
- ポイント付くのでやってみるかの精神
+3%弱とポイント0.8%なので悪くないけどポイント付かなくなったら止めるかも
確か出金に手数料がかかるんすよね。。。
LINEワンコイン投資とクラウドファンディングを申し込んだ
LINEワンコイン投資
とりあえずやってみてポイント取れなくなったら辞めるかな
クラウドファンディング
- SBIソーシャルレンディング
- SBI証券とかとはアカウント別っていうめんどくささ
- funds
- とりあえず作った
これらは面白い募集あったら突っ込むかもくらいの温度感
消費税10%まじ怖い
UIPageViewControllerのsetViewControllersでanimated: trueにしつつscrollViewのdelegateを奪い、無理やりbouncesを止めると挙動がおかしくなる件
タイトル長いんですが、無理やりPageViewControllerをいじるとおかしくなったのでメモ。 バージョン上がったらそのうち治るかも & そもそもやり方があれかも。
こういうよくある画面を作ってみた。 PageViewControllerで作っているので、両端にいった場合はbounceする(それでいいっちゃ良いんだけど)。
bouce止める場合はどうするんだろうと思い、「pageviewcontroller bounces stop」でググって出てきたやつを試す
bounce止めたやつ
暫定対応(アニメーションしない)
setViewControllersでanimated: falseにすればおかしくはない(アニメーションしないけど)
スタックオーバーフローをさまようと、PageViewControllerのキャッシュっぽさがあるけどよくわかんなかった。