rails レスポンスヘッダーをログ出力する
devise_token_authが返すレスポンスヘッダーをログに出力したくて調べた内容をメモしておく。app/controllers/application_controller.rbのafter_actionでheadersやresponseに入っていると思ったのだが期待した値はなく。controllerのaction実行後にdevise_token_authがヘッダーにセットしているのかな...
lib/HttpLogger.rb
class HttpLogger.rb def initialize(app) @app = app end def call(env) res = @app.call(env) // リエクスト puts "%s, %s, %s" % [env["HTTP_UID"], env["HTTP_CLIENT"], env["HTTP_ACCESS_TOKEN"]] // レスポンス(HTTPステータス、ヘッダー) puts "%s, %s" % [res[0], res[1]] res end end
config/application.rb
・・・ require "./lib/httplogger" module SampleAppApi class Application < Rails::Application ・・・ config.middleware.use ::HttpLogger end end
ちなみにHttpLoggerのcallのenvには他にも以下のような情報があった
SCRIPT_NAME QUERY_STRING SERVER_PROTOCOL SERVER_SOFTWARE GATEWAY_INTERFACE REQUEST_METHOD REQUEST_PATH REQUEST_URI HTTP_VERSION HTTP_HOST HTTP_ACCEPT HTTP_COOKIE HTTP_USER_AGENT HTTP_ACCEPT_LANGUAGE HTTP_ACCEPT_ENCODING HTTP_CONNECTION SERVER_NAME SERVER_PORT PATH_INFO REMOTE_ADDR
こんな力技たぶんじゃないとできないなんてありえないと思うのでもっとちゃんとしたやり方があればご教授お願いいたします。以上です
xcode カスタムURLスキームを本番と開発アプリで切替える
今回やりたかったことはカスタムURLスキームの設定。ブラウザから「myapp://」等のリンクをクリックしたときにアプリを起動させたいとかの場合に設定するものです。
アプリ開発していて、開発と本番アプリで別の名前で設定したいと思いやり方を調べたのでメモしておく。
作業のながれはざっくり以下
1. DebugとReleaseでそれぞれ別のURLスキームを定義(変数みたいなイメージ)
2. info.plistより1.で設定した変数を指定
3. DebugまたはReleaseを指定してビルド
1. TARGETS > Build Settingsの設定
1-1. TARGETS > Build Settings を選択して+ボタンで「Add User-Defined Setting」ボタンをクリック
1-2. User-Definedに「NEW_SETTING」が追加されるので名前を変更する。今回は「CUSTOM_URL_SCHEME」とする
1-3. 「CUSTOM_URL_SCHEMU」の「Debug」「Release」それぞれにURLスキームを設定する。
2. info.plistの設定
2-1. info.plistの「Information Property List」の+ボタンで項目を追加
2-2. 追加した項目を「URL Types」に変更して、「URL Identifier」の+ボタンで追加した項目を「URL Schemes」に変更して、$(CUSTOM_URL_SCHEME)を設定する
3. ビルド
3-1. キャプチャを参考に「Edit Scheme」を開く
3-3.「Build Configuration」より「Release」または「Debug」を選択
ここまで設定してビルドを行うとDebug、Releaseごとに別のURLスキームを選択できました。カスタムURLスキーム以外にアプリ名やBundleID等も切替える手順はこちらにまとめた
Xcode10 開発アプリと本番アプリで切替える - とりあえずphpとか
以上です
Xcode10 開発アプリと本番アプリで切替える
やりたいこと
・WebAPIのURLやSDKのキーの切替え
・BundleID、アプリ名の切替え
他にもやるべきことはありそうだけど自分の場合、とりあえずこれだけできれば最低限ok。
本番と開発環境だけでステージング環境とかはとりあえず考えない。
WebAPIやSDKのキーの切替え
デフォルトでマクロで「DEBUG」がtrueとなっているので条件分岐が可能
Env.swiftとか
struct Env { #if DEBUG static let API_URL = "開発環境のURLとk" static LET API_KEY = "開発環境のキーとか" #else static let API_URL = "本番環境のURLとか" static let API_KEY = "本番環境のキーとか" #endif }
・New Scheme...より本番用のスキームを追加
名前は「xxx-prod」とかにする。追加したら「Edit Scheme...」より「Run」の「Build Configuration」を「Release」に変更
これでこちらのスキームを選択してビルドすると本番用の分岐を通るようになる
アプリ名やBundleIDの切り替え
・Bundle Identifier
TARGETS > Build Settings > Product Bundle Identifier の値を変更
・アプリ名
TARGETS > Build Settings > Product Name の値を変更
以上です
Mac iconvでutf16からutf8へファイルの文字コード変換
古いxcodeで作ったプロジェクトをxcode10でビルドしようとしたらエラーになったので調べた
$ iconv -f UTF-16 -t UTF-8 /path/to/input > /path/to/output
以上です
migrate swift4.0 to swift4.2
swift4.0 から swift4.2 への修正内容メモしておく
UIKeyboardWillShow
UIResponder.keyboardWillShowNotification
UIKeyboardWillHide
UIResponder.keyboardWillHideNotification
UIControlEvents
UIControl.Event
UIEdgeInsetsInsetRect(rect, padding)
rect.inset(by: padding)
UIViewContentMode
UIView.ContentMode
addChildViewController
addChild
UIControlContentHorizontalAlignment
UIControl.ContentHorizontalAlignment
UITextBorderStyle
UITextField.BorderStyle
bringSubview(toFront: ***)
bringSubviewToFront(***)
UIAlertControllerStyle
UIAlertController.Style.alert
UIAlertActionStyle
UIAlertAction.Style
UIKeyboardFrameEndUserInfoKey
UIResponder.keyboardFrameEndUserInfoKey
UIActivityIndicatorViewStyle
UIActivityIndicatorView.Style
UITableViewCellStyle
UITableViewCell.CellStyle
UIImagePickerControllerSourceType
UIImagePickerController.SourceType
NSNotification.Name.UITextViewTextDidChange
UITextField.textDidChangeNotification
UIDatePickerMode
UIDatePicker.Mode
UIKeyboardFrameEndUserInfoKey
UIResponder.keyboardFrameEndUserInfoKey
popupViewController.didMove(toParentViewController: self)
popupViewController.didMove(toParent: self
UIApplicationLaunchOptionsKey
UIApplication.LaunchOptionsKey
NSAttributedStringKey
NSAttributedString.Key
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
UIImagePickerControllerImageURL
UIImagePickerController.InfoKey.imageURL
以上です
Swift LUExpandableTableViewを使って折りたたみ可能なUITableViewを実装
こんな感じのありがちなUI。ライブラリを使わずに自前で実装する方法もけっこう書いていただいている人がいて実装することはできたのだが、テーブルのレコード数が増えると開閉したときのスクロール位置がガタガタ。
自分の実装方法に問題があるかもしれないが細かいところまで解決できずいたところにこちらのライブラリを見つけた。少し同じ問題は発生するのだが自分でやるよりは全然マシでこちらを使うことにしたので使い方をメモしておく。
https://github.com/LaurentiuUngur/LUExpandableTableView
ViewController.swift
import UIKit import LUExpandableTableView class ViewController: UIViewController, LUExpandableTableViewDataSource, LUExpandableTableViewDelegate { var expandableTableView = LUExpandableTableView() override func viewDidLoad() { super.viewDidLoad() expandableTableView.frame = view.bounds view.addSubview(expandableTableView) expandableTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") expandableTableView.register(CustomHeader.self, forHeaderFooterViewReuseIdentifier: "CustomeHeader") expandableTableView.expandableTableViewDelegate = self expandableTableView.expandableTableViewDataSource = self } // MARK: - LUExpandableTableViewDelegate // セルの高さを返します func expandableTableView(_ expandableTableView: LUExpandableTableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 50 } // セクションヘッダーの高さを返します func expandableTableView(_ expandableTableView: LUExpandableTableView, heightForHeaderInSection section: Int) -> CGFloat { let header = CustomHeader() return header.setup(text: "セクションタイトル") } // MARK: - LUExpandableTableViewDataSource // セクション数を返します func numberOfSections(in expandableTableView: LUExpandableTableView) -> Int { return 100 } // セル数を返します func expandableTableView(_ expandableTableView: LUExpandableTableView, numberOfRowsInSection section: Int) -> Int { return 10 } // View(セル)を返します func expandableTableView(_ expandableTableView: LUExpandableTableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = expandableTableView.dequeueReusableCell(withIdentifier: "Cell") else { return UITableViewCell() } cell.textLabel?.text = "セル" return cell } // View(セクション)を返します func expandableTableView(_ expandableTableView: LUExpandableTableView, sectionHeaderOfSection section: Int) -> LUExpandableTableViewSectionHeader { guard let header = expandableTableView.dequeueReusableHeaderFooterView(withIdentifier: "CustomeHeader") as? CustomHeader else { return LUExpandableTableViewSectionHeader() } let _ = header.setup(text: "セクション") return header } }
CustomeHeader.swift
class CustomHeader: LUExpandableTableViewSectionHeader { var label = UILabel() var button = UIButton() override init(reuseIdentifier: String?) { super.init(reuseIdentifier: reuseIdentifier) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override var isExpanded: Bool { didSet { self.button.setTitle(isExpanded ? "閉じる" : "開く", for: .normal) } } func setup(text: String) -> CGFloat { backgroundView = UIImageView() backgroundView?.backgroundColor = UIColor.init(red: 157/255, green: 204/255, blue: 224/255, alpha: 1) label.frame = CGRect(x: 10, y: 0, width:UIScreen.main.bounds.size.width*0.8, height: 100) label.text = text label.font = UIFont.boldSystemFont(ofSize: 13) addSubview(label) button.frame = CGRect(x: label.frame.width, y: 0, width: UIScreen.main.bounds.size.width*0.2, height: 100) button.setTitle(isExpanded ? "閉じる" : "開く", for: .normal) button.setTitleColor(UIColor.black, for: .normal) button.titleLabel?.font = UIFont.systemFont(ofSize: 13) button.addTarget(self, action: #selector(onOpen(sender:)), for: .touchUpInside) addSubview(button) return button.frame.origin.y + button.frame.height } @objc func onOpen(sender: UIButton) { delegate?.expandableSectionHeader(self, shouldExpandOrCollapseAtSection: section) } }
以上です