お名前.comで取得した独自ドメインをHerokuでSSL対応しました
こんにちは。さくらです。
Web版ポケット糖質量(Railsで作っています。)をhttpのまま放置していたのですが、
やっとhttps対応しました。
https://www.pockettoushituryou.com/
このエントリーは覚書です。
Heroku側の設定
Automated Certificate Management(ACM)という機能を使います。
Automated Certificate Management | Heroku Dev Center
Herokuで独自ドメインに無料で、しかも自動でSSL対応出来る素敵な機能です。
ACMを有効化します。
$ heroku certs:auto:enable
ACMが有効になっているか確認します。
$ heroku certs:auto
私は失敗していました。後述するお名前.com側でのDNS設定をしていなかったからです。
Heroku からACM設定が失敗したよ、というメールも届きました。
TroubleshootingにDNSターゲットを「 {your-domain}.herokudns.com」という形式で指していなければならないとあります。
https://devcenter.heroku.com/articles/automated-certificate-management#troubleshooting
この設定をお名前.com側で行います。
お名前.com側の設定
お名前.comにログインします。
ドメイン取るならお名前.com【ドメイン取得は最安値1円〜】
ドメイン > ドメイン詳細 > ネームサーバー設定
の画面右上の「ドメイン設定」ボタンをクリックします。
DNS関連機能の設定をクリックします。
ドメイン一覧からドメインを選択して「次へ進む」ボタンをクリックします。
このような画面が表示されます。
DNSレコード設定を利用する の右の「設定する」ボタンをクリックします。
DNSレコード設定画面が表示されます。
「A/AAAA/CNAME/MX/NS/TXT/SRV/DSレコード」という欄に設定していきます。
example.comというドメインを設定する場合
項目 | 設定値 |
ホスト名 | www |
TYPE | CNAME |
TTL | 3600(デフォルト) |
VALUE | www.example.com.herokudns.com |
優先 | - |
状態 | 有効 |
入力したら「追加」ボタンを押します。
「確認画面へ進む」ボタンを押します。
確認画面が表示されるので、よければ「設定する」ボタンを押します。
[お名前.com]DNSレコード設定 完了通知というメールが届きます。
これで設定完了です。
しばらくしてからHeroku側を更新します。
$ heroku certs:auto:refresh
状態を確認します。
$ heroku certs:auto
1つしかDNS設定していないので1つ失敗したままですが、StatusがOKになりました。
私がやった時は変更から10分〜13分ぐらいでHeroku側のSSL対応も完了しました。
対応は以上です。
参考サイト様
Herokuアプリにお名前comで取得したドメインを設定 - americandog1993の日記
ありがとうございました(*‘ω‘ *)
UITableView + Static Cellsでアプリ内設定画面を作成するサンプル(XCode9, Swift4, StoryBoard使用)
アプリ内の設定画面のサンプルを作りました。
ステップ・バイ・ステップで作成方法を書いていきます。
※ 当初、記事を書いていたらチュートリアルっぽくなってきたので
チュートリアルとタイトルに付けていたのですが、
記事公開直後に私は特に設定画面のスタンダードに詳しくないから自信がない
と思ってしまったということと、
アプリのバージョンをSettings.bundleあたりでなくアプリ内の設定画面で表示するのは
イマイチな例だったかもしれないなーと思いつつあるんだけど
書いてしまったしな〜〜〜という状況になってしまったので、タイトルはサンプルにしました。
申し訳ありませんが、こんな例があるんだなーぐらいに受け止めていただければ幸いです。
グダグダとすみません(´-﹏-`;)
開発環境
環境はXcode9.2、Swift4.0を使用しています。
サンプルの仕様
このようなシンプルなものを作ります。
- 「名前」はクリックすると入力画面に遷移し、入力された値をUserDefaultsクラスを使ってアプリ内に保存します。
- 「アプリバージョン」はアプリ内でバージョンを取得して表示します。
- 「ライセンス」はUITableViewのセクション内の行数を2行にするためのダミーです。
サンプルの実装
新しくプロジェクトを作成します。
テンプレート選択の箇所は、iOS「Single View App」を選択します。
不要なクラスなどの削除
デフォルトで作成される「ViewController.swift」を右クリック > Deleteを選択して削除します。
Main.storyboardを開いてデフォルトで作成された「View Controller Scene」をクリック > deleteキーで削除します。
設定画面を設置する
Main.storyboardにObject Libraryから「Table View Controller」を設置します。
右側のAttributes Inspectorの中の「Is Initial View Controller」にチェックしておきます。
対応するクラスのファイルを作成します。
File > New > File… > Cocoa Touch Classを選択してNextボタンを押します。
次のダイアログで、Classを「SettingsTableViewController」、Subclass ofを「UITableViewController」にします。
Nextボタン > Createボタンを押し、作成します。
Main.storyboardを開き、左側のDocument Outlineから「Table View Controller」を選択します。
右側のIdentity InspectorのCustom ClassのClassを「SettingsTableViewController」にします。
左側のDocument Outlineから「Table View Controller」を選択して
Xcodeのメニュー > Editor > Embed In > Navigation Controller を選択します。
Table View sectionを設定する
左側のDocument Outlineから「Table View」を選択します。
右側のAttributes Inspectorの項目を次のように変えます。
Content | Static Cells |
Sections | 2 |
Style | Grouped |
左側のDocument OutlineからTable Viewの下の「Section-1」を選択します。
右側のAttributes InspectorのTable View Sectionの項目を次のように変更します。
Rows | 1 |
Header | 設定 |
同様に、「Section-2」を次のように変更します。
Rows | 2 |
Header | その他 |
Table View cellを設定する
左側のDocument Outlineから1つめの「Table View Cell」を選択します。
右側のAttributes InspectorのTable View Cellの項目を次のように変えます。
Style | Right Detail |
セルの内側のContent View の内側にある「Title」を選択して
Attributes InspectorのLabelのTextを「Title」→「名前」に変更します。
同様に「Detail」のTextを削除し、Colorはライトグレーを選択します。
同じように「その他」セクションを設定します。
セルの項目をソースコードに接続する
UITableViewでもStatic Cellsで作ったものは、通常の画面のように
直接セルの中のフィールドからソースコードにドラッグ&ドロップして
IBOutletの定義が出来ます。
Assistant Editorをクリックしてソースコードを開きます。
先程作成した「SettingsTableViewController」となっているのを確認してください。
名前のDetailをDocument Outlineから選択し、
コントロールキーを押しながらソースコードにドラッグします。
classの下あたりでドロップすると、ダイアログが表示されます。
Nameに「nameLabel」と入力してConnectを押します。
コードが挿入されます。
同様にアプリバージョンのDetailも「versionLabel」と入力してConnectします。
@IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var versionLabel: UILabel!
ソースコードの編集
セクションとセルの数を設定
Standard EditorでSettingsTableViewControllerを開きます。
まず次の2つの関数を変更します。その下にコメント行がたくさんありますが削除してしまって大丈夫です。
// MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { // #warning Incomplete implementation, return the number of sections return 0 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows return 0 }
次のように修正します。
// MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { // セクションの数を返します return 2 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // それぞれのセクション毎に何行のセルがあるかを返します switch section { case 0: // 「設定」のセクション return 1 case 1: // 「その他」のセクション return 2 default: // ここが実行されることはないはず return 0 } }
このようにセクションとセルの数を書かなければいけないところが手間ですね。
ここで画面左上のBuild and Runボタン(▶)を押して、一度実行してみます。
セルの右側には何も表示されませんが、ちゃんと表示されました。
アプリバージョンの表示
アプリバージョンを表示します。
viewDidLoad関数を次のように変更します。
override func viewDidLoad() { super.viewDidLoad() // アプリのバージョン if let version: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String { versionLabel.text = version } }
▶ボタンを押して実行してみます。
セルの右側にバージョンが表示されました。
バージョンにつきましては「CFBundleShortVersionString」で調べてみて下さい。
名前の表示
UserDefaultsの情報を画面にセットする
先程の関数のsuper.viewDidLoad()の下に次の行を書き加えて下さい。
// UserDefaultsの情報を画面にセットする if let name = UserDefaults.standard.value(forKey: "name") as? String { nameLabel.text = name }
アプリ内の保存領域から「name」というキーとセットになっている文字があれば画面にセットしています。
アプリ内の保存領域については「UserDefaults」で調べてみて下さい。
ただ、今は実行しても何も表示されません。
nameというキーで値を保存したことがないからです。
次に名前の入力画面を作成して保存、遷移元の画面も更新する処理を書いていきます。
名前の入力画面を作成
Main.storyboardを開いてObject Libraryから「Table View Controller」を設置します。
対応するクラスのファイルを作成します。
File > New > File… > Cocoa Touch Classを選択してNextボタンを押します。
次のダイアログで、Classを「SettingsNameTableViewController」、Subclass ofを「UITableViewController」にします。
Nextボタン > Createボタンを押し、作成します。
Main.storyboardを開き、左側のDocument Outlineから「Table View Controller」を選択します。
右側のIdentity InspectorのCustom ClassのClassをクリックして
「SettingsNameTableViewController」を選択します。
名前の入力画面へのセグエを追加
左側のDocument Outlineから
「Settings Table View Controller Scene」を選択し、「Table View」の下の
「設定」の下の「Table View Cell」を選択します。
そこから先程設置した画面の「Table View」までコントロールキーを押しながら
ドラッグします。
セグエの種類を選択するポップアップが表示されます。
「Show」を選択して下さい。
ここで▶ボタンを押して実行してみます。
名前のセルをクリックすると、次の画面が表示されます。
まだ何もない行が表示されるだけです。
名前の入力画面の設定
では、入力欄を定義していきます。
設定画面で行ったのと同じように、
左側のDocument Outlineから「Table View」を選択します。
右側のAttributes Inspectorの項目を次のように変えます。
Content | Static Cells |
Sections | 1 |
Style | Grouped |
セクションも編集します。
左側のDocument OutlineからTable Viewの下の「Table View Section」を選択します。
右側のAttributes InspectorのTable View Sectionの項目を次のように変更します。
Rows | 1 |
Header | 名前の編集 |
左側のDocument Outlineから「Content View」を選択します。
Object Libraryから「Text Field」を選択し、ドラッグ・アンド・ドロップで
Content View内に設置します。
設置したText Fieldを選択し、Constraintsを加えていきます。
次の画像のように、上下左右に16と入力してAdd Constraintsをクリックします。
入力欄の属性を4点変更します。
Attribute Inspectorを開いて次のように編集しましょう。
- Placeholderに「名前を入力してください」と入力します。
- デフォルトだと、入力欄の周りに囲み枠が付いているのでBorder Styleを一番左にして非表示にします。
- Clear Buttonを「Is Always visible」にします。
- 「Text Input Traits」の中の「Return Key」を「Done」にします。
セルの項目をソースコードに接続する
設定画面と同様にAssistant Editorをクリックしてソースコードを開きます。
先程作成した「SettingsNameTableViewController」となっているのを確認してください。
名前のText FieldをDocument Outlineから選択し、
コントロールキーを押しながらソースコードにドラッグします。
classの下あたりでドロップすると、ダイアログが表示されます。
Nameに「nameTextField」と入力してConnectを押します。
コードが挿入されます。
@IBOutlet weak var nameTextField: UITextField!
ここで実行してみますと、まだ名前の入力画面には何も表示されません。
ソースコードを編集しセクションとセルの数を記述することで表示されます。
セクションとセルの数を設定
Standard EditorでSettingsNameTableViewControllerを開きます。
設定画面と同じように修正します。この関数の後ろのコメント行も削除して大丈夫です。
// MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { // セクションの数を返します return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // それぞれのセクション毎に何行のセルがあるかを返します return 1 }
シンプルなサンプルなのでたった1つしかセクションとセルがありません。
▶ボタンを押して実行してみると入力欄が表示されるようになりました。
入力欄をクリックすると入力も出来ます。
まだ入力されたものをプログラム内で受取り保存する仕組みがないので、
前の画面に戻ったら消えてしまいます。
UITextFieldDelegateの実装
SettingsTableViewControllerクラスにUITextFieldDelegateプロトコルを実装します。
UITableViewControllerの後ろにUITextFieldDelegateを追加してください。
class SettingsTableViewController: UITableViewController, UITextFieldDelegate {
次にviewDidLoadの「super.viewDidLoad()」の後に次のコードを追加してください。
nameTextField.delegate = self
さらにソースコードの最後にデリゲートメソッドを追加します。
下記のコードを追加してください。
func textFieldShouldReturn(_ textField: UITextField) -> Bool { // keyboardを隠す textField.resignFirstResponder() return true }
このメソッドはリターンキーが押されたというイベントが発生した時に実行されます。
他にも色々なイベントを受け取れます。UITextFieldDelegateで調べてみて下さい。
入力中に表示されていたキーボードを隠す処理を入れました。
実行するとリターンキーを押した時にキーボードが隠れれば成功です。
入力した値の保存と表示
設定画面にUserDefaultsというアプリ内の保存領域の情報を画面に表示する処理を書きました。
if let name = UserDefaults.standard.value(forKey: "name") as? String { nameLabel.text = name }
"name"という名前のキーで情報があれば表示しています。
同じように名前の入力欄も情報があれば表示するよう変更します。
先程のviewDidLoad関数の nameTextField.delegate = selfの下に次の行を書き加えて下さい。
// UserDefaultsの情報を画面にセットする if let name = UserDefaults.standard.value(forKey: "name") as? String { nameTextField.text = name }
入力された内容の保存処理も記述します。
先程のtextFieldShouldReturn関数の
textField.resignFirstResponder()の下に次の行を書き加えて下さい。
// 入力された内容を保存する UserDefaults.standard.set(textField.text, forKey: "name")
"name"という名前のキーで保存しました。
実際のアプリの処理では、入力内容のチェックを行ったり、
余計なスペースを取り除いたり、保存ボタンを付けたりすると思いますが
ここではサンプルのため無条件にリターンキーを押されたら保存することになります。
▶ボタンを押して実行してみます。
何か入力してリターンキーを押します。
前の設定画面に戻ると名前の右側に入力したものは表示されていません。
あらためて名前のセルを押して入力画面に遷移すると、
先程入力した文字が入力欄にセットされていると思います。
設定画面に戻った時に表示されなかったのは、
UserDefaultsの変更があった時に変更通知を受け取る処理が記述されていないからです。
もう一度▶ボタンを押して実行すると今度は表示されるはずです。
設定画面でUserDefaultsの変更があった時に画面を更新する
設定画面を編集してUserDefaultsの変更通知を受け取る処理を記述します。
SettingsTableViewController.swiftを開きます。
viewDidLoadの「super.viewDidLoad()」の後に次のコードを追加してください。
// UserDefaultsの変更を監視する NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: nil)
ソースコードの最後の「 } 」の直前に次のコードを追加してください。
@objc func userDefaultsDidChange(_ notification: Notification) { // UserDefaultsの変更があったので画面の情報を更新する if let name = UserDefaults.standard.value(forKey: "name") as? String { nameLabel.text = name } } deinit { // UserDefaultsの変更の監視を解除する NotificationCenter.default.removeObserver(self, name: UserDefaults.didChangeNotification, object: nil) }
既にUserDefaultsに保存済なので一度アプリをアンインストールしてから
▶ボタンを押して実行してみます。
入力後に設定画面に戻ると入力内容が表示されます。
解説は以上となります。
全体のソースコードはこちらにあります。
github.com
以上です。
iOSでRealmのデータファイルの場所の見つけ方
初期データのあらかじめ入ったRealmのファイルを用意しておき、
アプリに組み込んで使いたいと思っています。
それにはデータが入ったDBのファイルが必要です。
Realmの保存場所を特定する方法をメモしておきます。
前提
環境はXcode9.2、Swift4.0を使用しています。
初期データ作成用のXcodeプロジェクトを作っておきます。
実機かシミュレーターにRunしておきます。
参考サイト様
ありがとうございます!!!
https://realm.io/docs/swift/latest/#copying-objects-between-realms
How to find my realm file? - Stack Overflow
シミュレーターにインストールした場合の場所
// DBのファイルの場所 print(Realm.Configuration.defaultConfiguration.fileURL!)
このコードでファイルパスを表示してくれます。
これをコピーします。
finderを開いてCommandキー+Shiftキー+Gを押します。
先ほどのパスを貼り付けます。
先頭の「file://」は削除して移動します。
実機にインストールした場合
Xcodeのメニューから Window > Devices and Simulators を選択します。
実機にインストールされているアプリが一覧で表示されます。
アプリを選択します。
左下の設定アイコンをクリック > “Download Container…“を選択します。
保存ダイアログが開きます。プロジェクトルートがデフォルトの保存場所になっています。
◯◯.xcappdataという名前がセットされているのでそのまま保存します。
Finderで保存した場所を開きます。
◯◯.xcappdataを右クリックして「パッケージの内容を表示」(英語表示の場合「“Show Package Contents”」)をクリックします。
ここにあります。
AppData / Documents / default.realm
以上です。