2019年3月30日土曜日

Storybordで制約を付け直す(Xcode、iOS)


こんにちは、オフィス狛 モバイル開発担当 Aika-yuy です。


viewを動的に消したり、表示したり、大きさを変更したいときなどに制約も修正しなければいけないと思います。

そんな時にコードで修正するのが面倒。。なんてことはないでしょうか。
そこでstorybordで簡単に制約を付け直す方法をご紹介します。
コードでの修正はとても少なく、使いやすいです。

まず、3つのviewを用意し、間を均等に60空ける制約をつけます。

今回は、動的にyellowViewを消す場合をやってみます。

黄色のviewを消してみました。
黄色のviewがなくなっても、赤と青のviewの位置はそのままです。

それでは、変更したい制約をstorybordで作ります。


redViewのbottomとblueViewのtopの間を60空ける制約をつけました。
この時制約同士が、ぶつかってしまうので後からつけた制約を無効にしなければなりません。
写真では、無効にしてあるので、色が薄くなっています。こうなっていればOKです。


上の写真のように、installedのチェックを外すだけです!!

それができたら、viewControllerに接続します。


後は消したいタイミングで .isActiveをtrueにするだけです。

と言いたいところですが、、、、、
制約の変更はスレッドセーフではない為、メインスレッドで実行しないと反映されません。
DispatchQueue.main.async {}で囲みましょう。

























うまくできました!!!

class ViewController: UIViewController {

    @IBOutlet weak var redView: UIView!
    @IBOutlet weak var yellowView: UIView!
    @IBOutlet weak var blueView: UIView!
    @IBOutlet weak var changeConstraint: NSLayoutConstraint!
    @IBOutlet weak var blueViewConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.yellowView.isHidden = true
        
        DispatchQueue.main.async {
            self.blueViewConstraint.isActive = false
            self.changeConstraint.isActive = true
        }
    }
}



2019年3月29日金曜日

Illustratorのワークスペースでの色と書き出した時の色が違う時はカラー設定のせいかもしれません。


こんにちは、オフィス狛 デザイン部のSatoです。

Illustratorで画像を書き出した時に「あれ?きちんとドキュメントのカラーモードをRGBに設定していたのにIllustrator上での色と書き出した時の色が違う……?」と思った経験がありませんか?
そんな時に見直すべきだなと思うのがカラー設定です。

Illustratorを使っている方ならだいたい知っている基礎的な話なのですが、新規ファイルを作成するとカラー設定が戻ってしまうバグで私自身焦ったので今後似たようなバグがあった時用に記載しておこうと思います。
https://forums.adobe.com/docs/DOC-9568←私の環境で起こった現象はこのバグに近いですがちょっと違うようでした)


Illustratorカラー設定を確認するにはまず、メニューバーの「編集」のカラー設定をクリックして出てくるカラー設定の設定セレクトボックスを「Web ・インターネット用-日本」に変更すればweb用に書き出した際の色で作業できるようになります!簡単!

初期設定である「Adobe Illustrator5.5をエミュート」に設定されてる場合のワークスペースと「Web ・インターネット用-日本」に設定されてる際のワークスペースの色の違いはこんな感じです。
「Adobe Illustrator5.5をエミュート」での見え方はなんだか薄いです。

ちなみにですが、私がカラー設定が「Adobe Illustrator5.5をエミュート」になっていると気づいたのは作業中のワークスペースの色がなんだかおかしいので色の校正を間違って設定したのかと思いメニューを確認したところ、「色の校正」が使えない状態になっており、調べたところカラー設定が「Adobe Illustrator5.5をエミュート」になっていると使えないという情報が出てきたからです。

調べたところ、数ヶ月前から起こっているバグなのに現在もまだ修正されていないようですね……。
もし色がおかしいな?と思ったら「カラー設定」を見直してみてください。


2019年3月28日木曜日

MySQLでAUTO INCREMENTの値を取得したい。


オフィス狛 技術部のJoeです。

INSERT後にAUTO INCREMENTで自動採番された値を使用したいことがあるかと思いますが、
MySQLでは前回INSERTのAUTO INCREMENT値を「LAST_INSERT_ID()」関数で取得できます。

テーブルを作成して、1件INSERTすると「1」が取れました。
mysql> CREATE TABLE test (
    -> id   INT         NOT NULL PRIMARY KEY AUTO_INCREMENT,
    -> name VARCHAR(10) NOT NULL );
mysql> INSERT INTO test ( name ) VALUES ( '111' );
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+

AUTO INCREMENTは一意であることを保証してくれますので、各セッション内で最後にINSERTした値が取れました。
【セッションA】INSERT INTO test ( name ) VALUES ( '111' );
【セッションB】INSERT INTO test ( name ) VALUES ( '222' );
【セッションB】SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                2 |
+------------------+
【セッションA】SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+

と、便利な関数ですが、想定する値が取れないパターンも併せてをご紹介します。

●AUTO INCREMENTのカラムに値を指定してINSERTした場合
値を指定してしまうと取得できません。同一セッションで前回自動採番された値が取れるようです。
mysql> INSERT INTO test ( name ) VALUES ( '111' ); -- 値を指定しない(自動採番)
mysql> INSERT INTO test ( id, name ) VALUES ( 10, '222' ); -- 値を指定する
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+

●単一のINSERT文で複数データをINSERTした場合
3件INSERTしたので「3」が欲しいのですが、「1」が取れました。
mysql> INSERT INTO test ( name ) VALUES ( '111' ), ( '222' ), ( '333' );
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+

●別セッションの場合
「当然!」と言われそうですが、別セッションでは取得できません。
下記のようなDB接続から開始するAUTO INCREMENT値の取得処理みたいなものを作ってしまうと、想定した値が取れませんでした。
(MySQLへの接続は「MySql.Data.MySqlClient」を使っています)

[ C#でMySQL接続してAUTO INCREMENT値を取得(ダメな例) ]
string conString= "Database=test;Data Source=localhost;User Id=test;Password=test";
public void Index()
{
    using (MySqlConnection con = new MySqlConnection(conString))
    {
        // DB接続→INSERT
        con.Open();
        MySqlCommand cmd = con.CreateCommand();
        MySqlTransaction tran;
        tran = con.BeginTransaction();
        cmd.Connection = con;
        cmd.Transaction = tran;
        try
        {
            cmd.CommandText = "INSERT INTO test (name) VALUES ('1111')";
            cmd.ExecuteNonQuery();
            tran.Commit();
            ShowAutoIncrementId();  // AutoIncrementの値を表示
        }
        catch (Exception)
        {
            tran.Rollback();
        }
    }
}

public void ShowAutoIncrementId()
{
    using (MySqlConnection con = new MySqlConnection(conString))
    {
        // DB接続→AutoIncrementIdを取得して表示する
        con.Open();
        MySqlCommand cmd = con.CreateCommand();
        cmd.Connection = con;
        cmd.CommandText = "SELECT LAST_INSERT_ID()";
        object id = cmd.ExecuteScalar();
        System.Diagnostics.Debug.WriteLine("***** ID : " + id);
        return;
    }
}

【1回目の実行】
INSERTとSELECTが別セッション(428と429)になってしまったので取得できませんでした。
■結果
***** ID : 0
■MySQLログ
2019-03-06T07:39:31.579862Z 428 Query INSERT INTO test (name) VALUES ('111')
2019-03-06T07:39:31.582475Z 428 Query COMMIT
2019-03-06T07:39:31.660854Z 429 Connect test@localhost on test using SSL/TLS
2019-03-06T07:39:31.668533Z 429 Init DB test
2019-03-06T07:39:31.668751Z 429 Query SELECT LAST_INSERT_ID()

【2回目の実行】
なぜか「1」が取れました!?
コネクションプールで、1回目のINSERTと2回目のSELECTのセッションIDが同じ(428)になると、前回INSERTのIDが取得できてしまうようです。
■結果
***** ID : 1
■MySQLログ
2019-03-06T07:39:40.390591Z 429 Query INSERT INTO test (name) VALUES ('111')
2019-03-06T07:39:40.393070Z 429 Query COMMIT
2019-03-06T07:39:40.469436Z 428 Init DB test
2019-03-06T07:39:40.469689Z 428 Query SELECT LAST_INSERT_ID()


AUTO INCREMENTの値は、主キーや外部キーなどで使用することがあるかと思いますので、
「LAST_INSERT_ID()」関数を使用される際はご注意ください。

2019年3月27日水曜日

踏み台サーバー(EC2)経由でSQLServer(RDS)にSSH接続する方法(ポートフォワーディング)


オフィス狛 技術部のHammarです。

最近はAWSで環境を作って開発する機会が多いですが、ここでセキュリティ的な部分や運用的な観点としてよく踏み台サーバー経由で目的のサーバーに接続するということがあると思います。
今回はその「踏み台サーバー(EC2)経由でSQLServer(RDS)に接続する」という目的で、接続したSQLServerをSQL Server Management Studio (SSMS) で操作したいと思います。

■利用環境

Windows(ローカルPC)
AWS ES2(踏み台)
AWS RDS(SQL Server)

■利用ツール

SQL Server Management Studio
teraterm

今回の目的を達成するには、「SSHポートフォワーディング」というテクニックを利用します。
ポートフォワーディングとは、SSHによって確立した通信経路を利用して、クライアントのポートを、クライアントが直接アクセスできないサーバのポートに転送してくれる仕組みを指します。

これを利用して今回の手順は簡単に書くと下記のようになります。
   ①踏み台サーバーにSSH接続
   ②踏み台サーバーからSQL Serverにポート転送(ポートフォワーディング)
   ③ポートフォワーディングした状態でSQLServerにログインしDB操作


では上記手順を踏まえて、具体的な手順を書いていきます。

1.teratermでポートフォワード設定する

よくSSH接続につかわれるツールで有名なteratermには、デフォルトでポートフォワード設定機能がついていて、これを利用します。

①teratermを起動し、メニューバーの「接続」→「SSH転送」を選択
②ポート転送画面で「追加」ボタンを押下

③ポート転送を行う向きの選択で「ローカルのポート」にチェックを入れ下記のように設定します
   ローカルのポート:11433(何でもよい)
   リモート側ホスト:接続するRDSのエンドポイント
   ポート:1143

④OKを選択する


2.teratermで踏み台にSSH接続する

次に踏み台にSSH接続するのですが、このとき1で設定したポートフォワード機能が有効になり、踏み台に接続したと同時に目的のサーバーにも接続されることになります。(トンネルを掘った状態にするともいいます)

①teratermメニューバーの「ファイル」→「新しい接続」で下記のように設定します
   ホスト:EC2のエンドポイント
   TCPポート:22
   サービス:SSHにチェック

②SSH認証画面でEC2へ接続するための認証情報を設定する
  ※基本ユーザー名と鍵設定で行けると思います

③OKを選択してSSH接続する


3.SSMSでログインする

1、2まででポートフォワーディングは完了しているので、この接続をつなげたままであとはツール(今回はSSMS)で直接SQLServerにつなげるだけです。
接続設定は下記のように設定します。
   サーバー名:127.0.0.1,11433
   認証:SQL Server認証
   ログイン:ルート権限ユーザー名
   パスワード:設定したパスワード

サーバー名は[127.0.0.1]のローカルホストを指定し、カンマでポート指定できますので、先ほど1で設定したローカルのポート(11433)をここに設定することで、 ローカルから踏み台サーバー経由、ポートフォワーディングでSQL Server接続が可能になります。

あとはSSMSで操作が可能なので、ツール内でデータベース作ったりテーブル作ったりが簡単にできます。


今回のポートフォワーディングを利用することで、もちろんSQL Server以外でも接続可能ですし、いろいろ応用できると思いますので、ぜひ参考にしてみてください。


, , , ,