元柔道整復師エンジニアBlog

- 元柔道整復師エンジニアBlog -

『 エンジニアをリングする。』

【PHP】Visual Studio Codeで定義元へのジャンプ機能を設定する

目的

  • Visual Studio Code(以降VSCode)で展開したPHPリソースにて、定義元へのジャンプを可能にしたい
  • Eclipseみたいな定義元へのジャンプ機能を再現したい

前提

  • PHP環境はDockerにて構築
  • Docker内にあるPHPリソースをVSCodeで展開
  • そのためPCにはPHP自体のインストール等はしていない

環境

手順

PHPをインストールする

PC自体にPHPをインストールしていない場合はインストールする。
今回は、php-7.2.10-Win32-VC15-x64 をインストールしました。
※とくに仮想マシン等でのPHPを管理している場合においても、PHPをインストールしておく必要がある

設定ファイル php.iniの作成・編集

ダウンロードしたら適当なディレクトリに解凍し、
解凍されたら、php-7.2.10-Win32-VC15-x64みたいなディレクトリができる。→バージョンによって若干差異あり

その解凍されたディレクトリ内にあるphp.ini-developmentファイルを同階層にコピーして、ファイル名をphp.iniに変更し保存する。

保存したphp.iniファイルを開き、以下2点の設定を編集する。

1.ディレクトリ設定を有効にする

コメントアウト;を外す。

(変更前)
;extension_dir = "ext"
(変更後)
extension_dir = "ext"

2.sslのextensionを有効にする

コメントアウト;を外す。

(変更前)
;extension=openssl
(変更後)
extension=openssl

拡張機能 PHP Intellisenseをインストールする

VSCode拡張機能である「PHP Intellisense」をインストールする。
PHP IntellisensePHPコードの補完・整形を可能とする拡張機能らしいので、これがないとはじまらない...

settings.jsonの設定を変更する

VSCodesettings.jsonを開く。
[右下の歯車アイコン] > [Settings] > [Extentsions] > [PHP] > [Edit in settings.json]
または
[File] > [Preferences] > [Settings] > [Extentsions] > [PHP] > [Edit in settings.json]
を選択する。

開いたら、 php.validate.executablePathの編集ボタンを押下し、右側に表示されるWORKSPACE SETTINGSにjson形式で以下2行を追加する。

{
    "php.validate.executablePath": "PHPインストール時に解凍したディレクトリ内にあるphp-win.exeのパス",
    "php.suggest.basic": false
}

実際はこんな感じ

{
    "php.validate.executablePath": "C:\\Users\\ユーザー名\\php-7.2.10-Win32-VC15-x64\\php-win.exe",
    "php.suggest.basic": false
}

記入したら、保存(Ctrl+S)する。 これで VSCodePHPが認識されるようになる。

あとは再起動すればOK!

参考

【Xcode】実機接続時にProvisioning profile "*" doesn't include the currently selected device "*".

環境

事象

新しい実機をXcode上に接続後、ビルドすると「Provisioning profile "Profile名" doesn't include the currently selected device "実機名"」が発生し失敗する。

前提

  • 他の実機では接続後、ビルドこのうなことを確認済みである。
  • 本実機において、Apple DevelopperにてUDIDの設定と対象プロジェクト用のProvisioning Profileのダウンロードは完了済みである。

類似した事象(原因ではない)

本事象と類似した参考があったが原因ではなかった記事

原因

ダウンロードした既存プロジェクトのProvisioning Profilesにおいて、本実機のUDIDが登録(紐付け)ができていなかった。

解決

Apple Developperにて、既存のProvisioning Profilesに本実機のUDIDを紐づける。

  1. Apple Developperにて [Certificates, Identifiers & Profiles] > [Provisioning Profile]を選択する。
  2. 選択後、対象のProvisioningProfileを選択し、[Edit]を選択する。
  3. 選択したProvisioningProfileの登録デバイス(UDID)が表示される。
  4. 下にある [Devices] に本実機のUDIDが表示されるので、チェックをつける。
  5. チェック後、[Genarate] を選択し登録する。
  6. 登録したProvisioningProfileのダウンロードを勧められるので [Download] を選択する。
  7. 「〇〇.mobileprovision」というファイルがダウンロードされるので、ダブルクリックしてXcodeに反映する。

【Swift】 TextFieldをタップした時に全選択できるようにする

環境

目的

TextFieldをタップした時に、TextFieldの値が存在する場合において全選択をできるように設定する。

準備

  • ViewControllerにUITextFieldDelegateを設定する。
class ViewController: UIViewController, UITextFieldDelegate {

    // UITextFieldの定義
    @IBOutlet weak var myTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // UITextFieldDelegateの設定
        self.urlTextField.delegate = self
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        // ここに本処理を記述していく
    }

}

処理

1. TextFieldの選択範囲を指定する方法:textRange(from: UITextPosition, to: UITextPosition)
func textFieldDidBeginEditing(_ textField: UITextField) {

    // TextFieldの選択範囲を最初から最後まで(全選択)に指定する
    textField.selectedTextRange = textField.textRange(
        from: textField.beginningOfDocument,
        to: textField.endOfDocument) 
}
2. TextField内の文字列を選択状態にする方法:selectAll(sender: Any?)
func textFieldDidBeginEditing(_ textField: UITextField) {

    // nilチェック
    if textField != self.urlTextField {
        return
    }
    
    // TextField内の文字列を選択状態にする
    textField.selectAll(self.textField.text)
}

問題

2回に1度しか全選択の状態にならない

1回目にTextFieldをタップした時は全選択ができているが、再度繰り返し同じ動作をすると全選択とならない。

再現
  1. シュミレータ起動後、対象のTextFieldを選択(タップ)する。
  2. キーボードが上がり、TextFieldが全選択される。
  3. 確認後、TextField以外の部分を選択し、TextFieldの選択状態を解除する(キーボードが下がった状態)。
  4. 再度、対象のTextFieldを選択(タップ)する。
  5. TextField上で全選択がされず、通常の選択状態となる or 選択動作が上手くされない

原因

調べてみたら、以下の同事象と似ている記事を見つけました。

stackoverflowより

これによると、 遅延処理を加えると解消されるとあったので、実際に試してみる

遅延処理について

遅延処理を加える実装方法(以下3つ)とその参考記事をまとめてみました。

色々記事を見た結果、 今回はSwift3以降で使用可能となったdispatch_afterを適用させてみようと思います。

対処

遅延処理dispatch_afterの適用

1.の「TextFieldの選択範囲を指定する方法」に適用する
func textFieldDidBeginEditing(_ textField: UITextField) {

    // 遅延処理 → 0.1秒後に実行
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // TextFieldの選択範囲を指定する
    textField.selectedTextRange = textField.textRange(
        from: textField.beginningOfDocument,
        to: textField.endOfDocument)
    }
}
2.の「TextField内の文字列を選択状態にする方法」に適用する
func textFieldDidBeginEditing(_ textField: UITextField) {

    // nilチェック
    if textField != self.urlTextField {
        return
    }
        
 // 遅延処理 → 0.1秒後に実行
 DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
        // TextField内の文字列を選択状態にする
        textField.selectAll(self.textField.text)
    }
}

修正後、「2回に1度しか全選択の状態にならない」が解消され、 TextField選択時に全選択されるようになった。

参考

[Swift] TextField全選択時の処理で「2回に1度しか全選択の状態にならない」場合の対処方法

【Swift】シュミレータ起動時に「Attempt to present <*> on <*> whose view is not in the window hierarchy!」が発生したときの対処方法

環境

事象

ViewContorollerのviewDidLoadメソッド内において、アラート表示させる処理を以下のように追加し、

override func viewDidLoad() {
    super.viewDidLoad()
    
    // アラート表示
    self.showAlert("Message Alert!!")
}

// アラート表示の処理
func showAlert(_ alertMessage: String) {
    let alertConroller = UIAlertController(
        title: "Alert", message: alertMessage, preferredStyle: .alert)
    let originAction = UIAlertAction(
        title: "OK", style: .default, handler: nil)
    alertConroller.addAction(originAction)
    self.present(alertConroller, animated: true, completion: nil)
}

シュミレータを起動するとコンソール上に、 「アラートを表示しようとしたが、Viewがないため追加できない」というがエラー出る。

2018-05-02 21:44:12.082835+0900 ***App[88818:8813297] Warning: Attempt to present <UIAlertController: 0x7f929b88a600> on <***App.ViewController: 0x7f929b6114a0> whose view is not in the window hierarchy!

原因

iOSのライフサイクルに反していることによるもの。

アラートは本来、Viewを構築ViewDidLoad()したあとに追加しなければいけないため、 エラー内容通り、Viewがない状態でアラートを表示(追加)することができないということであった。

[参考記事]

対処

アラート表示の処理は、Viewが構築された(画面描画が終わった)あとに追加する必要があるため、 Viewの読み込み終了時に呼ばれるViewDidLoad()内ではなく、画面描画の終了時に呼ばれるviewDidAppear()というメソッドが用意されているのでそこに処理を追加する。

// View構築
override func viewDidLoad() {
    super.viewDidLoad()
}

// View構築後の処理
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    // アラート表示
    self.showAlert("Message Alert!!")
}

// アラート表示の処理
func showAlert(_ alertMessage: String) {
    let alertConroller = UIAlertController(
        title: "Alert", message: alertMessage, preferredStyle: .alert)
    let originAction = UIAlertAction(
        title: "OK", style: .default, handler: nil)
    alertConroller.addAction(originAction)
    self.present(alertConroller, animated: true, completion: nil)
}

【Swift】 UIButtonボタンの有効化・無効化を設定をする

環境

目的

  • UIButtonボタンの有効化・無効化の設定をする

実行

UIButtonボタン定義後に、ボタンに対し有効化・無効化の設定をisEnabledで行う。
isEnabledには、真偽値を設定する。

// ボタン定義
@IBOutlet weak var button: UIButton!
・
・
// 有効化・無効化の設定
self. button.isEnabled = true  // 有効
self. button.isEnabled = false // 無効

まとめ

  • ボタン押下時の順不動な処理を防ぐ。
  • ボタンの重複押下への対策となる。