エンジニアのはしがき

プログラミングの日々の知見を書き連ねているブログです

Macbookのクラムシェルモードが作動しなくて悩んだ話

f:id:tansantktk:20210224222109p:plain

クラムシェルモードって何?

Macbookを折りたたんだ時に、ディスプレイの映像を有線接続した外部ディスプレイに出力するモードのことを指します。

  • Macbookのディスプレイでは小さくて見辛い!!
  • 大き目のディスプレイに出力したい!!

といった時におススメのモードです。

クラムシェルモードが作動するには条件がある

Apple公式によれば、下記の条件があるようです。

Mac ノートブックをクラムシェルモードで使うには、以下の準備が必要です。

  • AC 電源アダプタ、または USB-C や Thunderbolt 3 (USB-C) で電力を供給する外付けのディスプレイ。
  • 外付けのキーボードとマウスまたはトラックパッド (USB 接続またはワイヤレス)。
  • USB-C - USB アダプタまたはケーブル (USB-C ポートを搭載した Mac で USB マウスやキーボードを使う場合)。
  • 外付けのディスプレイまたはプロジェクタ。

Mac ノートブックコンピュータの内蔵ディスプレイを閉じた状態で外付けのディスプレイを使う - Apple サポート

上記に加え、クラムシェルモードが有効になる条件として、MacBook本体はACアダプタで電源供給されている状態に保つ必要があります

私の場合、ACアダプタを接続していなかった為に、何度試しても外部ディスプレイに画面が出力されず、四苦八苦しました😰

本当にただのうっかりミスだったのですが、気づくまで1時間程要してしまい、大事な大事な開発時間を消費してしまいました。 せめてエラーなり警告か何か出してくれたら良いのにと思ってしまう今日この頃でした…。

Swiftでガワネイティブなアプリを作ろう!

f:id:tansantktk:20210224211159p:plain

ネイティブアプリでUIを作り込もうとすると何かと仕様について調べることが多く、苦労することが多いと思います。 個人的な意見ですが、今まで慣れ親しんだHTML, js, cssとは勝手が違い、Swiftでは思うようなUIを実現することが出来ず頭を抱えました🤢

WebViewを使えばネイティブアプリ上にブラウザ機能を貼り付けてしまうことが可能です。俗に言うガワネイティブというやつです。

要件にもよりますが、WebViewの活用は開発者の負荷を減らすことにも繋がります。 今回はSwiftでガワネイティブなアプリの作り方を公開していきたいと思います!

続きを読む

AngularのViewChild()の値はビューの初期化まではundefinedである

どうも、最近小規模な失敗談が尽きません…😭 今回はその中から、フレームワーク仕様の理解不足による失敗談を晒していきたいと思います!

ハマったこと

とあるComponentでViewChild()デコレータで取得したプロパティを参照しようとしたところ、undefinedがだった為にその後の処理で例外になった。

今回、以下のソースコードのような内容を書いていました。(実際のコードとは異なります)

import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, AfterViewInit {
  title = 'sample';
  @ViewChild('foo') fooElement;

  ngOnInit() {
    // コンポーネントの初期化時にthis.fooElementを参照したかった
    console.log(this.fooElement.nativeElement.id);
  }
}

this.fooElementにはテンプレートで定義したHTMLElementが代入される…はずでした。

f:id:tansantktk:20210217195517p:plain

しかし、this.fooElement = undefinedだった為、参照エラーに。

ViewChild()とは

テンプレートで定義した要素や子コンポーネントを参照し、プロパティに格納したい時に使うデコレータです。 親コンポーネント側から子コンポーネントのメソッドやプロパティを呼びたい時や、特定要素の値を参照したい時によく使います。

何故undefinedだったのか

ViewChild()で参照しようとしている値が代入されるタイミングは、ビューの初期化が完了した後だった為です。

ビューの初期化が完了した後というのは、ライフサイクルメソッドであるngAfterViewInit()が呼び出されたタイミングということになります。

↓ライフサイクルメソッドについては公式を確認下さい。

delete-circleci-and-firebase--angular-ja.netlify.app

先ほどのソースコードでは、ライフサイクルメソッドngOnInit()の中でViewChild()した値を参照しようとしていました。 しかし、ngOnInit()ngAfterViewInit()より前の段階で呼び出されるメソッド(=ビューの初期化が未完了の状態)である為、 undefinedとして処理が進行してしまっていたわけです。

修正後

import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, AfterViewInit {
  title = 'sample';
  @ViewChild('foo') fooElement;

  ngOnInit() {
    // ngOnInit()内ではthis.fooElementは参照しない
  }

  ngAfterViewInit() {
    // ビューの初期化が完了してからthis.fooElementを参照する
    console.log(this.fooElement.nativeElement.id);
  }
}

f:id:tansantktk:20210217195916p:plain

無事、this.fooElement.nativeElement.idを参照することができました。

ViewChild()は便利なデコレータですが、代入されるタイミングはしっかり意識しながらコーディングが必要です🤤

AWS Glue(Python shell)をLambda代わりに使ってタイムアウトを伸ばす

f:id:tansantktk:20210221135248p:plain

AWS Lambdaは、サーバ自体のお守りが不要なのでさくっとバックエンドを構築したい場合はかなり便利です。 ただ難点を挙げるならば、タイムアウトが15分までしか伸ばせない点。 これは残念ながら仕様となっているのでどうしようもできません。

Lambda のクォータ - AWS Lambda

ただ、EC2で構築するとなるとサーバ管理が必要になり、現在の配置人員的にも保守コストがかかり過ぎる… ということで無理やりAWS GlueをLambda代わりにしました。

続きを読む

ASP.NET CoreがLambda上で何故か動かず四苦八苦した

f:id:tansantktk:20210221134731p:plain

何が起こったか

フロントエンドから呼ばれるAPIサーバをAWS Lambda(ASP.NET Core)で構築していたのですが、 とあるリリース作業時に最新バージョンをLambdaへデプロイした後、APIサーバが常にエラーを返すようになってしまいました。

原因

ASP.NET Coreの環境設定用ファイルのアクセス権限が所有者以外全て拒否されていた🤤

ASP.Net Coreではappsettings.jsonを用意して、環境設定を読み込めるのですが このファイルのアクセス権限が何故か書き換わってしまっていました。 リリース作業途中に環境設定ファイルをGoogle Drive等に一時的に移動したり戻したりといったことをしたせいかもしれません。

実際にターミナルで調べてみると以下のようにアクセス権限が無いことが分かったので、アクセス権限を付与し直してデプロイすることで解決しました。 原因は物凄く単純なことだったのですが、CloudWatchのエラーログを見ても原因特定が難しく、1時間程溶かしてしまいました…。

$ ll

# 所有者以外のアクセス権限が無い
-rw------- 1 ******* 197609    850 Jan 17 12:59 appsettings.json

# アクセス権限を付与
$ chmod 666 appsettings.json

# Lambda上でもアクセス可能になった
-rw-rw-rw- 1 ******* 197609    850 Jan 17 12:59 appsettings.json

ChromeのデベロッパーツールでWebサイトをデバッグ・検証しよう

f:id:tansantktk:20210128231458p:plain

今回はChromeのデベロッパーツールについて、普段よく使う機能に絞ってまとめていきます。

続きを読む

InstrumentsでiOSアプリのモニタリングをする

f:id:tansantktk:20210123185206p:plain

こんばんは! 前回のSwiftのメモリリークをやらかした話に関連して、負荷のチェックについても調べたので残しておきたいと思います。

↓以前メモリリークでやらした話はこちら

tm-progapp.hatenablog.com

続きを読む

Swiftで循環参照によるメモリリークを起こしてしまった話

f:id:tansantktk:20210122185759p:plain

こんばんは!今回は題名の通りSwiftでの失敗談です。

無知は罪なりとはよく言ったものですがそれを再確認させられました🤤

続きを読む

APIGateway+Lambdaによるアプリサーバをバージョン管理する

APIGatewayの統合リクエストとLambdaの組み合わせでバックエンドを構成することが多いのですが、最近になってバージョニングが出来ることを知り、いろいろと調べてみた結果を書き連ねていきたいと思います!

続きを読む

Raspberry Piで動画のストリーミングをしてみる

f:id:tansantktk:20210114203415p:plain

自宅で水耕栽培をしているのですが、植物の成長度合いをブラウザからでも見てみたいという気持ちから ラズパイで動画のストリーミングサーバを立ててみました!

続きを読む