20200209のMacに関する記事は12件です。

Share Extensionのハマりポイント

はじめに

初の個人アプリを App Store に審査出したら 30 分足らずでリリースされてビビったからその全てをお伝えしますの記事を見てShare Extensionいいなぁと思い自分のアプリにもつけてみよう!と思ったのですが色々ハマりました...

対象

  • iOS13.0以上
  • macOS Catalina

Share Extensionの実装

ここを参考に実装をしました。

Share Extension の追加自体は簡単でした。

ShareViewController の POST 機能とかいらなかったので参考記事に書いてあったように下記のように修正して画面を作成しました。

ShareViewController.swift
- class ShareViewController: SLComposeServiceViewController {
+ class ShareViewController: UIViewController {

画面は下記のようなものでテキストのみ共有するようにしました。(上下に TextView を置いています。上が共有文字列で下はまだ実装中)

share_ios_screen

共有メニューに表示されない

なぜか共有メニューにアプリが表示されない時がありました:scream:

info.plist
<key>NSExtensionAttributes</key>
<dict>
 <key>NSExtensionActivationRule</key>
 <dict>
  <key>NSExtensionActivationSupportsText</key>
  <true/>
 </dict>
</dict>

上記のようにしてると共有メニューに表示されず参考記事のように SUBQUERY にすると表示されるようになりました:tada:

info.plist
<key>NSExtensionActivationRule</key>
 <string>SUBQUERY (extensionItems,$extensionItem,
  SUBQUERY ($extensionItem.attachments,$attachment,
    (ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text" 
    || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.plain-text")
  ).@count == $extensionItem.attachments.@count).@count == 1
 </string>

画面が閉じれない

iOS Mac
share_ios_screen share_mac_screen

上記のように iOS 版は半モーダルなので下にスワイプすれば閉じれますが Mac 版の場合は閉じることができません:scream:

こちらも参考記事に閉じる方法が書いてありました:heart_eyes:

閉じるボタンを用意して下記のようにすれば閉じることができました:tada:

@IBAction private func cancel(_ sender: Any) {
  extensionContext!.completeRequest(returningItems: nil, completionHandler: nil)
}

共有メニューのローカライズ

iOS Mac
share_ios share_mac

上記のように iOS 版は共有メニューにもアプリのターゲットで設定した Display Name が表示されます(ローカライズも対応)が Mac 版は Share Extension のターゲットで設定した Display Name が表示されています:scream:

Share Extension のターゲットに InfoPlist.strings を下記のように追加しました。

InfoPlist.strings
CFBundleDisplayName = "DNA Converter"; // (Japaneseの方は "DNA変換" と設定)

これで Mac版 でもアプリ同様共有メニューにも日本語表示なら「DNA変換」英語表記なら「DNA Converter」と表示されるようになりました:tada:(どっかに変数を設定してアプリのターゲットと共通化すべきなのかも?)

共有した値が取得できない

致命的なのですが Mac 版で共有した値が取得できませんでした:scream:

共有したテキストの取得処理は下記のように実装しました。

let extensionItem: NSExtensionItem = extensionContext?.inputItems.first as! NSExtensionItem
guard let itemProvider = extensionItem.attachments?.first else {
  // ここでなんかエラー処理
  return
}

let publicText = String(kUTTypeText)  // "public.text"
if itemProvider.hasItemConformingToTypeIdentifier(publicText) {
  itemProvider.loadItem(forTypeIdentifier: publicText, options: nil, completionHandler: { (data, error) in
    guard let text = data as? String else {
      // ここでなんかエラー処理
      return
    }
    // ここでなんか処理
  })
  return
}

let publicPlainText = String(kUTTypePlainText)  // "public.plain-text"
if itemProvider.hasItemConformingToTypeIdentifier(publicPlainText) {
  itemProvider.loadItem(forTypeIdentifier: publicPlainText, options: nil, completionHandler: { (data, error) in
    guard let text = data as? String else {
      // ここでなんかエラー処理
      return
    }
    // ここでなんか処理
  })
  return
}

// ここでなんかエラー処理

iOS では下記のように extensionContext?.inputItems.firstNSExtensionItemAttachmentsKey に値が入っているのですが

 po extensionContext?.inputItems
 Optional<Array<Any>>
   some : 1 element
    - 0 : <NSExtensionItem: 0x6000007e4260> - userInfo: {
    NSExtensionItemAttachmentsKey =     (
        "<NSItemProvider: 0x600002edc690> {types = (\n    \"public.plain-text\"\n)}"
    );
    NSExtensionItemAttributedContentTextKey = {length = 317, bytes = 0x7b5c7274 66315c61 6e73695c 616e7369 ... 20417070 6c65207d };
    "com.apple.UIKit.NSExtensionItemUserInfoIsContentManagedKey" = 0;
}

Mac では下記のように値が入っていません...

po extensionContext?.inputItems
 Optional<Array<Any>>
   some : 1 element
    - 0 : <NSExtensionItem: 0x6000018d45c0> - userInfo: {
    NSExtensionItemAttachmentsKey =     (
    );
    NSExtensionItemAttributedContentTextKey = {length = 315, bytes = 0x7b5c7274 66315c61 6e73695c 616e7369 ... 30204170 706c657d };
}

色々試してみましたが Mac 版では値が取得できませんでした。extensionContext?.inputItems.firstNSExtensionItemAttributedContentTextKey からがんばれば取得できそうですがなんか違うと思いあきらめました。

ここにきて思ったのが Mac 版だけ動作がおかしいのでそもそも Share Extension が Mac に対応してないんじゃね?という疑惑です。(なんか知ってる人いたら教えて下さい)

ということで私は Mac 版の Share Extension はあきらめました:confused:

Mac版で取得できた値(20200211追記)

コメントでURLは取れると聞いたので他の値が取れるかみてみました。

info.plist を下記に設定して extensionContext?.inputItems をログで出してみました。

info.plist
<key>NSExtensionAttributes</key>
<dict>
  <key>NSExtensionActivationRule</key>
  <string>TRUEPREDICATE</string>
</dict>

URL

 Optional<Array<Any>>
   some : 1 element
    - 0 : <NSExtensionItem: 0x6000013e8660> - userInfo: {
    NSExtensionItemAttachmentsKey =     (
        "<NSItemProvider: 0x600003aeddc0> {types = (\n    \"public.url\"\n)}",
        "<NSItemProvider: 0x600003aedea0> {types = (\n    \"public.image\"\n)}"
    );
}

Image

 Optional<Array<Any>>
   some : 1 element
    - 0 : <NSExtensionItem: 0x600002034630> - userInfo: {
    NSExtensionItemAttachmentsKey =     (
        "<NSItemProvider: 0x60000092f3a0> {types = (\n    \"public.image\"\n)}"
    );
}

Movie

 Optional<Array<Any>>
   some : 1 element
    - 0 : <NSExtensionItem: 0x6000013d1ef0> - userInfo: {
    NSExtensionItemAttachmentsKey =     (
        "<NSItemProvider: 0x600003ae0230> {types = (\n    \"com.apple.quicktime-movie\",\n    \"public.file-url\",\n    \"public.url\"\n)}"
    );
}

PDF

 Optional<Array<Any>>
   some : 1 element
    - 0 : <NSExtensionItem: 0x6000013c54f0> - userInfo: {
    NSExtensionItemAttachmentsKey =     (
        "<NSItemProvider: 0x600003ae43f0> {types = (\n    \"public.url\"\n)}",
        "<NSItemProvider: 0x600003ae5ff0> {types = (\n    \"com.adobe.pdf\"\n)}"
    );
}

まとめ

Type 結果
text :x:
url :o:
image :o:
movie :o:
pdf :o:

テキストだけ取れない:poop:

さいごに

Mac 版はなにか特殊な設定がいるんでしょうか?調べた限り有力な情報は得られませんでした...

情報求ム!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

macでminicomを使う方法

自分があとで見返して思い出せるようにとの意味も込めて書きます。
スクショ貼りは後日行います。

minicomの設定は

minicom -s

macに接続されているデバイスを調べる方法

ls -l /dev/tty.usb*
crw-rw-rw- 1 root 9, 6  1 29 20:55 /dev/tty.usbserial-FTU83NYP

設定ファイルを保存する



設定ファイルでminicom起動

minicom RS232C_COM_DEBUG
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

-bash: ls: command not foundの解決方法

-bash: ls: command not found(macのコマンドが使えない)

現象

$ ls
-bash: ls: command not found
$ vim ~/.bash_profile
-bash: vim: command not found

macのコマンドが全然使えない。。。

原因

~/.bash_profileの変更後に起きたので、PATHの設定が誤って消えてしまっていたのではと予想。

解決方法

$ /usr/bin/vi ~/.bash_profile

でPATHの設定を確認して、、

$ export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin":$PATH

でPATHを追加。※最後の:$PATHを入力しないと、追加したPATH以外は消えてしまうので注意。

無事にコマンドが使えるようになった!!

参考

https://gabekore.org/mac-path-environmental-variable
https://qiita.com/fuwamaki/items/3d8af42cf7abee760a81

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

macOSにAWS CLI をインストールする

概要

自身のMacにAWS CLIをインストールした時の備忘録。
公式ドキュメントを元に作業。

環境

  • macOS Catalina

前提条件

  • Python 2 バージョン 2.7 以降または Python 3 バージョン 3.4 以降

構築

Pythonのバージョン確認

$ python --version
Python 2.7.16

バージョン2.7以降のPythonがインストールされているから前提条件をクリアしているが、
なんとなく、Python3もインストールする。

Python3 インストール

# パッケージの検索
$ brew search python3
==> Formulae
boost-python3       python3             python@3            python@3.8

# Python3 インストール
$ brew install python3

# python3 インストール確認
$ python3 --version
Python 3.7.6

これで、Python3でインストールする準備が整ったので、次にAWS CLIをインストールする。

# AWS CLI ダウンロード
$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"

# AWS CLI 解凍
$ unzip awscli-bundle.zip

# AWS CLI インストール (Pythonのバージョンを指定してインストール)
$ sudo /usr/local/bin/python3 awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws

# AWS CLI インストール確認
$ aws --version
aws-cli/1.17.13 Python/3.7.6 Darwin/19.3.0 botocore/1.14.13

Pythonのバージョンは、デフォルトバージョンで実行されてしまうため、デフォルトバージョンを変更するか、Pythonアプリケーションの絶対パスを指定してあげる必要がある。今回は「/usr/local/bin/python3」の部分で絶対パスを指定して実行している。

デフォルトのバージョンを変更したい場合は、pyenvでバージョン切り替えを行うと良さそう。

参考

参考:https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-macos.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Python】スクリーンショットをとる

環境

・Mac Catalina
・Python 3.8.1

Macでの設定

そのままだと、スクリーンショットをとってもデスクトップがとられてしまうため、
画面収録の許可を行います。

『システム環境設定』→『セキュリティとプライバシー』

システム環境設定.jpg

『画面収録』にターミナルにチェックを入れる。

画面収録.jpg

スクリーンショットをとる

pyautoguiをインストールします。

pip install pyautogui

pyautogui.screenshot()で全画面のスクリーンショットをとれます。

import pyautogui

screenshot = pyautogui.screenshot()
screenshot.save('スクリーンショット.png')

全体.jpg

範囲を指定する場合

region = (左からの配置位置, 上からの配置位置, 幅, 高さ)を使用することで、
特定範囲のスクリーンショットをとれます。

import pyautogui

screenshot = pyautogui.screenshot(region = (100, 200, 1500, 875))
screenshot.save('スクリーンショット.png')

範囲指定.jpg

JPEGで保存する場合

RGBに変換することで、 JPEGで保存することができます。

screenshot = screenshot.convert('RGB')

参考

容量の大きいpngファイルを、jpgファイルに変換する
pyautogui

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初期構築で Homebrew で追加したほうがいいもの

はじめに

Mac の初期構築で入れておきたいパッケージを必ずと言っていいほど忘れてしまうので、ここに書き残しておきます。「これ便利ですよ」 とかあれば是非コメントよろしくお願いします。

Home brew とは ?

Home brew は mac の パッケージ管理システム です。個別にパッケージをインストールしてしまうと、後々アップグレードや削除などを行いたいときに面倒なことになってしまいますよね。
( パッケージを探してから諸々コマンドを打たないといけないので。 )

加えて、何のパッケージをインストールしているかなんて時が経てば忘れてしまうものですよね。
それを 全て解決してくれる のがパッケージ管理システムです。

つまり

  • brew コマンドを叩くだけ でパッケージのインストール・追加・削除・アップグレードなどなどができる
  • パッケージの 依存関係も管理 してくれる
  • 何のパッケージが入っているかなどが 一覧で確認 できる

などが実現可能です。

macOS オペレーティングシステム上のパッケージ管理システムのひとつである。同じく macOS のための MacPorts や Fink と同様の目的と機能を備え、利用が広がりつつある。Linux の Debian の APT に似た使用感である。
( By Wikipedia )

Homebrew

Home brew のサイト からインストールのためのコマンドをコピーできます。
公式サイト.png

インストール
# brew のインストール
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

# バージョン確認
$ brew -v

Homebrew 2.2.5
Homebrew/homebrew-core (git revision 1252; last commit 2020-02-08)
Homebrew/homebrew-cask (git revision d266c; last commit 2020-02-09)

問題なくインストールができていればバージョンが表示されます。
Xcode Command Line Tools のダウンロードはまとめて行ってくれるようにアップデートされています。 )

追加するもの

tig (formula)

Git の CUI クライアントです。普段は GUI で git 操作を行いますが、コマンドで操作するときなどもあるため入れています。
tig はかなりメジャーなパッケージかなと思います。

readline (formula)

readline は、行編集用のライブラリで bashvim など、様々なところで使われています。
こちらは CUI 上でファイル表示・編集をする際に使われるパッケージですので追加します。( tig で必要となります。)

mySql (formula)

mysql は言わずもがなであるリレーショナルデータベース( RDB )ですね。ローカルでは Docker コンテナの中で DB を立ち上げたりする方が多いかもですが、入れておいて損はないですよね。

nodebrew (formula)

Node.js のバージョン管理パッケージですね。
こちらもウェブアプリケーションエンジニアであれば入れている方が多いパッケージですね。

openssl @1.1(formula)

証明書関連 のパッケージです。

OpenSSL は、SSL プロトコル・TLS プロトコルの、オープンソースで開発・提供されるソフトウェアである。中心となっているライブラリは基本的な暗号化関数と様々なユーティリティ関数を実装している。様々なコンピュータ言語で OpenSSL ライブラリを利用できるようにするラッパーもある。
(By Wikipedia)

protobuf (formula)

こちらは プロトコル関連 のパッケージです。
brew で他のパッケージを追加した際に必要となり併せて追加されたみたいです。

brew cask

brew 本体とは異なり、こちらは GUI パッケージを管理するシステム です。
chrome とかのブラウザとかいろいろバージョン管理できます。

iTerm2

こちらは ターミナルエミュレータ です。 mac 標準のコンソールも使い勝手は悪くありませんが、複数台のサーバに接続したりするときに画面分割するなど便利ですよね。 bash → zsh に変更して利用しています。

source tree

git の GUI クライアントです。push, rebase など基本的な操作は全てボタンポチッで完了できます。



こちらの記事は随時更新していく予定です。
再度になりますがお勧めのパッケージなどありましたらコメントいただけると幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【使用例あり】ディレクトリ構成を出力するtreeコマンドをMacOSで実行する

treeコマンドを導入することで、以下のようにディレクトリ構成を一目で確認することが可能です。

% tree
.
├── sample1-1.txt
├── sample1-2.txt
└── sampleDir2
    ├── sample2-1.txt
    ├── sample2-2.txt
    ├── sample2-3.txt
    └── sampleDir3
        └── sample3-1.txt

Homebrew導入

Homebrew が入っていない人は、最初に Homebrew をインストールしましょう。

Homebrewのインストール

% /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Homebrewバージョン確認

% brew -v
Homebrew 2.2.5
Homebrew/homebrew-core (git revision 1252; last commit 2020-02-08)
Homebrew/homebrew-cask (git revision d266c; last commit 2020-02-09)

最新バージョンをインストール

% brew update

treeコマンド導入

以下のコマンドを実行してtreeコマンドをインストールします。

treeコマンドインストール

% brew install tree

これで導入は完了。

treeコマンドの使用方法

構成を確認したいフォルダにcdコマンドで移動したあと、treeコマンドを実行します。

% tree [オプション] [ディレクトリ...]

使用例

ディレクトリ sampleDir1 の構造をtreeコマンドで見てみます。
以下の.sampleDir1 を表しています。

% tree
.
├── sample1-1.txt
├── sample1-2.txt
└── sampleDir2
    ├── sample2-1.txt
    ├── sample2-2.txt
    ├── sample2-3.txt
    └── sampleDir3
        └── sample3-1.txt

-dオプション(ディレクトリのみ表示)

% tree -d
.
└── sampleDir2
    └── sampleDir3

-Lオプション(表示する深さを指定)

% tree -L 1
.
├── sample1-1.txt
├── sample1-2.txt
└── sampleDir2

1 directory, 2 files

-Pオプション(条件に一致したファイルを表示)

% tree -P "sample2*"
.
└── sampleDir2
    ├── sample2-1.txt
    ├── sample2-2.txt
    ├── sample2-3.txt
    └── sampleDir3

-uオプション(ファイルの所有者を含めて表示)

% tree -u
.
├── [username ]  sample1-1.txt
├── [username ]  sample1-2.txt
└── [username ]  sampleDir2
    ├── [username ]  sample2-1.txt
    ├── [username ]  sample2-2.txt
    ├── [username ]  sample2-3.txt
    └── [username ]  sampleDir3
        └── [username ]  sample3-1.txt

2 directories, 6 files

-gオプション(ファイルの所有グループを含めて表示)

% tree -g
.
├── [staff   ]  sample1-1.txt
├── [staff   ]  sample1-2.txt
└── [staff   ]  sampleDir2
    ├── [staff   ]  sample2-1.txt
    ├── [staff   ]  sample2-2.txt
    ├── [staff   ]  sample2-3.txt
    └── [staff   ]  sampleDir3
        └── [staff   ]  sample3-1.txt

-sオプション(ファイルのサイズ(バイト数)を含めて表示)

% tree -s
.
├── [          0]  sample1-1.txt
├── [          0]  sample1-2.txt
└── [        192]  sampleDir2
    ├── [          0]  sample2-1.txt
    ├── [          0]  sample2-2.txt
    ├── [          0]  sample2-3.txt
    └── [         96]  sampleDir3
        └── [          0]  sample3-1.txt

-Dオプション(ファイルの更新時刻を含めて表示)

% tree -D
.
├── [Feb  9 16:48]  sample1-1.txt
├── [Feb  9 16:48]  sample1-2.txt
└── [Feb  9 16:49]  sampleDir2
    ├── [Feb  9 16:49]  sample2-1.txt
    ├── [Feb  9 16:49]  sample2-2.txt
    ├── [Feb  9 16:49]  sample2-3.txt
    └── [Feb  9 16:49]  sampleDir3
        └── [Feb  9 16:49]  sample3-1.txt

参考

【 tree 】コマンド――ディレクトリをツリー状に表示する

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker for Windows and Mac

WindowsとMacそれぞれにDockerを導入する手順を記述する.(2020年2月9日現在)
いろんな方の記事を参考にさせていただいています.ありがとうございます.

Windows

はじめに現在使っているのがHomeなのかProなのかを確認する.

cmd
> systeminfo

「OS 名: 」以降を確認します。

Homeの場合

Proの場合

yper-V(仮想化システム)がサポートされているため
Docker for Windowsを使用します。

Hyper-Vの有効化

コントロールパネルの[プログラム]-[Windowsの機能の有効化または無効化]から「Hyper-V」にチェックを付けます。
※有効化するにはOSの再起動が必要です。

Docker for Windowsのインストール

以下のサイトから.exeファイルをインストール
https://docs.docker.com/docker-for-windows/install/
安定板のStable channelを選びます。

「Add shortcut to desktop」にチェックを付けて「OK」をクリックします。
インストール終了後、ダイアログの指示通りLog outして
「OK」を選択することでOSの再起動が行われます。

参考

Mac

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Mac] Alacrittyで Ctrl-Q と Ctrl-[ がきかなかった話

はじめに

先日、せっかくだからMacにもAlacrittyを入れてみようかな~と思い、

$ brew cask install alacritty

でインストールしてさわってみていたところ、

「あれ、Ctrl-Qがきかない…?」

となり、調べて対応したメモです。

環境

  • MacBook Air (macOS Catalina)

Ctrl-Q

正確には、Ctrl-Qを2連打しないと、AlacrittyがCtrl-Qの入力を認識してくれない、という症状でした。

私はCtrl-QをTmuxのプリフィクスキーに割当てていて、これは死活問題だぞ…と。

対応

とりあえずGitHubを見てみると、ちょうどドンピシャのissueがあがっていました。

ちょうど2日前(2020/02/07)に解決されていたのですが、昨日の今日でリリースに反映されているはずもないので、自前でビルドしました。

Cargoのインストール

まずRustのパッケージマネージャ兼ビルドツールであるCargoこちらの手順に従いインストールします。

$ curl https://sh.rustup.rs -sSf | sh

インストールがすんだら、画面の指示に従いPATHをとおすようにして、

$ . ~/.bash_profile

でPATHを反映します。

Alacrittyのビルド

続いて、Alacrittyをビルドします。

$ git clone git://github.com/alacritty/alacritty.git alacritty
$ cd alacritty
$ make app
$ cp -r target/release/osx/Alacritty.app /Applications/

動作確認

Alacrittyを起動し、Ctrl-Qを試しに押してみると、「動いた!!!」

…と喜んだのも束の間、今度は「あれ、Ctrl-[動かなくね…?」ということで次に続きます。

Ctrl-[

どの環境でも、というわけにはいきませんが、EscapeCtrl-[で代替することができます。私も環境が許してくれれば、ホームポジションから遠いEscapeの代りにCtrl-[を使います。

AlacrittyでVimを立上げ、INSERTモードからNORMALモードに戻ろうとCtrl-[を押すと、今度は「あれ、モードが変らねえ…。」
一方Escapeを押すと、ちゃんと認識してNORMALモードに戻ってくれました。

対応

~/.config/alacritty/alacritty.ymlの最下部にキーバインド例が載っており、これを参考にしてCtrl-[Espaceに置換えるキーバインドを追加します。

alacritty.yml
# ↓のコメントアウトをはずす
key_bindings:
  # (Windows, Linux, and BSD only)
  #- { key: V,        mods: Control|Shift, action: Paste            }
  #- { key: C,        mods: Control|Shift, action: Copy             }
  #
  # ...(中略)...
  #
  #- { key: Home,      mods: Shift,   action: ScrollToTop,    mode: ~Alt       }
  #- { key: End,       mods: Shift,   action: ScrollToBottom, mode: ~Alt       }
  #
  # ↓以下を追記
  - { key: "LBracket",       mods: Control,   chars: "\x1b" }

動作確認

Alacrittyを起動してCtrl-[を試しに押してみると「動いたぞ!!!」

ということで、めでたし、めでたし。

おわりに

そのうちHomebrewやリリースにも反映されるだろうと思います。Ctrl-[の方は、私の環境依存の問題かもしれないですが、お困りの方がいたら取り急ぎの策ということで、ご参考になれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PowerShell で API を叩いてみる

はじめに

表題のまま!
きっかけはこれ↓
業務改善をしよう!目次編

※PC環境が Mac しかないため、PowerShell Core を Mac にインストールして実施しています。
インストール方法はこちら

結論:Invoke-WebRequest か Invoke-RestMethod を使う

外部通信というと curl が思い浮かびますが、残念ながら curl そのものは初期状態では入っていません。
2020/2/10 追記
→バージョンにより curl が最初から入っている場合もあるそうです。コメントでご指摘いただきました。
@ktz_aliasさん、ありがとうございます!

今回は前提として他のチームメンバーにも共有しますので、あまりインストール作業とかさせないようにしたい…

それに、せっかくだから PowerShell のやり方でやってみたいしね

というわけで早速結論ですが、Invoke-WebRequestInvoke-RestMethod を使うことで外部通信を行うことができます。
この2つの違いとは…?ここに載せても良かったのですが、日本語記事だと特にトップには出てこなかったので、せっかくなので別記事で書くことにしました。記事の記載が終わり次第こちらにもリンクを張っておきます。
2020/2/10 追記
書きました。
Invoke-WebRequestとInvoke-RestMethodの違い

で、一応この違いを調査する前に Invoke-WebRequest で学習を進めてしまっていたので今回はこちらを簡単に紹介したいと思います。

Invoke-WebRequest を使ってみる

とりあえずサッと叩いてみましょう。
適当に叩ける API を調べたら下記が出てきたので使わせてもらっています。
【随時更新】一風変わったWeb APIをまとめてみた

$web = Invoke-WebRequest "https://yesno.wtf/api"
$web

StatusCode        : 200
StatusDescription : OK
Content           : {"answer":"no","forced":false,"image":"https://yesno.wtf/as
                    sets/no/15-7446b1035f784986609f456e15d30a5b.gif"}
RawContent        : HTTP/1.1 200 OK
                    Transfer-Encoding: chunked
                    Connection: keep-alive
                    Status: 200 OK
                    Cache-Control: must-revalidate, max-age=0, private
                    Access-Control-Allow-Origin: *
                    ETag: "5c579cddf84cec8bef9c616b7da260…
Headers           : {[Transfer-Encoding, System.String[]], [Connection, System.
                    String[]], [Status, System.String[]], [Cache-Control, Syste
                    m.String[]]…}
Images            : {}
InputFields       : {}
Links             : {}
RawContentLength  : 108
RelationLink      : {}

ちなみに [Invoke-WebRequest] は全て小文字でも問題ないです。
というか PowerShell 特有のコマンド(正しくはコマンドレット)は基本的に大文字小文字関係ないみたいです。

叩き方は GET メソッドということもあり、そこまで curl と異なる感じでもなくむしろまんまですね。
流石にオプションは異なりますが、ややこしいこともなく、そんなに違和感感じないかと。

主に使うものとしてヘッダーの設定だけちょっと癖があるかなって感じですね。
PowerShell の場合はヘッダーの設定はこうなります。

Invoke-WebRequest -Method POST -Headers @{"Authorization"="Basic XXX";"Content-Type"="application/json"} ~...

さて話を戻しまして、レスポンスを見てもらえば分かる通り、少し通常の応答とは異なります。
これは PowerShell における独自のオブジェクトで、これらのいずれかを取得したい場合は下記のように記載します。

$web.Content

{"answer":"no","forced":false,"image":"https://yesno.wtf/assets/no/15-7446b1035f784986609f456e15d30a5b.gif"}

もちろんこうして使ってもよいのですが、こんなことも

$hoge = ConvertFrom-Json $web
$hoge

answer forced image
------ ------ -----
no      False https://yesno.wtf/assets/no/15-7446b1035f784986609f456e15d30a5b.…

$hoge.answer

no

PowerShell には jq 相当のコマンドは用意がないため、jq っぽく使いたい時は上記のようにオブジェクトを変換して指定してあげると使いやすいかと思います。

ぶっちゃけ言いますと、先述したような Json の応答を期待する API を叩く時は WebRequest でなく RestMethod のほうが良さげです。
なんでかって話ですが、これまた先述したように別記事にあげますのでそちらを参照ください。
(というか実際に打ってみたほうが早い)

せっかく PowerShell を使うのであれば、特有のものを色々調べつつ進めていきたいですね。
それでは!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WebView開くと大量のエラーログが出たので調べた

どんなエラーか

エラー内容は以下の通り
[Process] kill() returned unexpected error 1
これが10ミリ秒ごとくらいに発生するので他のログが埋れて非常に面倒。

発生条件

ログが大量に出るだけでアプリ自体がクラッシュしたりはないので
気づくまで結構経ってたんですが、どうやらWebViewを使用している画面で発生する様子

WebviewのあるViewコントローラーへの遷移時、Webviewのスクロール時
あとWebView内(html)でダイアログを出してる間とかにも発生。

調べてみる

Google先生にエラー内容を聞いてみると同様の現象が発生している人がいっぱいいた。
てっきり自分がなんか実装ミスったかな?とかWebコンテンツ側がバグってんのかな?
とかFireBaseの所為か?とか思ってたけど、どうやらWebKitのバグの様子
雑に実装してたツケが回ってきたかと思ったけどそうじゃなくてよかった

AppleDeveloperFormsでも同様の質問がされてて、13.3でも修正は入っていないみたい。

chintan100
Dec 11, 2019 11:26 AM
(in response to neal1)

Still exists in 13.3!
How much more time before the WebKit fix is integrated into iOS?!
Super frustrating bug!

わかるよchitan100まさにSuper frustrating bug

いつ修正される?

WebKit Bugzillaで見ると、既に報告/修正済み
? 原因と修正内容

ということはどのバージョンで修正が入ったものがリリースされるかだけども
WebKitのリリースノートを確認すると...
WebKit Release Note

おや?

This release covers WebKit revisions 249750-250329.

This release covers WebKit revisions 249750-250329. ?

? ? ?
250329.

なおっていないんだけど...
どういうことですか....

まとめ

・バグの原因はWebkitにある
・すでに修正はコミット済み
・修正入りバージョンのリリースはされていない(リリースしてるってけどなおっていない?)

結論:修正バージョンリリース待ち!

修正バージョンリリースまではLogに何かしら分かりやすい目印でもつけて
Filterとかで対応するしかなさそうですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

macで軽量DNSサーバ dnsmasqを使う

背景

macでローカルにdnsを建てて名前解決をしたい場面が出てその際に行った作業メモ

dnsmasqとは

dnsmasqとは小規模ネットワーク向けのDNS/DHCP/TFTPサーバです。
同じDNSサーバとしてbindが有名ですがbindに比べて導入コストや設定方法の簡易さと言ったメリットがあげあれます。
DNSクエリをキャッシュすることで以前に訪れたことのあるサイトへの接続速度を向上が見込めます。

dnsmasq/dnsmasq

インストール

dnsmasq

brewを使ったインストールで完了です。
設定はdnsmasq.confというファイルを使用するので作成します。

$ brew install dnsmasq
$ touch /usr/local/etc/dnsmasq.conf
$ sudo ln -s /usr/local/etc/dnsmasq.conf /etc/dnsmasq.conf

dnsをローカルに設定します。(hostsより優先度を高くすれば良いのみで既に設定がある場合は優先度の高い位置へ挿入すればOKです)

$ sudo vi /etc/resolv.conf

nameserver 127.0.0.1
nameserver 192.168.0.1
nameserver 8.8.8.8

macでdnsキャッシュのクリア

hosts変えたりした際に動作が期待通りにならないことがある。
その際に下記を実行することでdnsのキャッシュをクリアすることができる。

$ sudo killall -HUP mDNSResponder

usage

nsmasq --help
Usage: dnsmasq [options]

Valid options are:
-a, --listen-address=<ipaddr>                          Specify local address(es) to listen on.
-A, --address=/<domain>/<ipaddr>                       Return ipaddr for all hosts in specified domains.
-b, --bogus-priv                                       Fake reverse lookups for RFC1918 private address ranges.
-B, --bogus-nxdomain=<ipaddr>                          Treat ipaddr as NXDOMAIN (defeats Verisign wildcard).
-c, --cache-size=<integer>                             Specify the size of the cache in entries (defaults to 150).
-C, --conf-file=<path>                                 Specify configuration file (defaults to /usr/local/etc/dnsmasq.conf).
-d, --no-daemon                                        Do NOT fork into the background: run in debug mode.
-D, --domain-needed                                    Do NOT forward queries with no domain part.
-e, --selfmx                                           Return self-pointing MX records for local hosts.
-E, --expand-hosts                                     Expand simple names in /etc/hosts with domain-suffix.
-f, --filterwin2k                                      Don't forward spurious DNS requests from Windows hosts.
-F, --dhcp-range=<ipaddr>,...                          Enable DHCP in the range given with lease duration.
-g, --group=<groupname>                                Change to this group after startup (defaults to dip).
-G, --dhcp-host=<hostspec>                             Set address or hostname for a specified machine.
-h, --no-hosts                                         Do NOT load /etc/hosts file.
-H, --addn-hosts=<path>                                Specify a hosts file to be read in addition to /etc/hosts.
-i, --interface=<interface>                            Specify interface(s) to listen on.
-I, --except-interface=<interface>                     Specify interface(s) NOT to listen on.
-j, --dhcp-userclass=set:<tag>,<class>                 Map DHCP user class to tag.
-J, --dhcp-ignore=tag:<tag>...                         Don't do DHCP for hosts with tag set.
-k, --keep-in-foreground                               Do NOT fork into the background, do NOT run in debug mode.
-K, --dhcp-authoritative                               Assume we are the only DHCP server on the local network.
-l, --dhcp-leasefile=<path>                            Specify where to store DHCP leases (defaults to /usr/local/var/lib/misc/dnsmasq/dnsmasq.leases).
-L, --localmx                                          Return MX records for local hosts.
-m, --mx-host=<host_name>,<target>,<pref>              Specify an MX record.
-M, --dhcp-boot=<bootp opts>                           Specify BOOTP options to DHCP server.
-n, --no-poll                                          Do NOT poll /etc/resolv.conf file, reload only on SIGHUP.
-N, --no-negcache                                      Do NOT cache failed search results.
-o, --strict-order                                     Use nameservers strictly in the order given in /etc/resolv.conf.
-O, --dhcp-option=<optspec>                            Specify options to be sent to DHCP clients.
-p, --port=<integer>                                   Specify port to listen for DNS requests on (defaults to 53).
-P, --edns-packet-max=<integer>                        Maximum supported UDP packet size for EDNS.0 (defaults to 4096).
-q, --log-queries                                      Log DNS queries.
-Q, --query-port=<integer>                             Force the originating port for upstream DNS queries.
-R, --no-resolv                                        Do NOT read resolv.conf.
-r, --resolv-file=<path>                               Specify path to resolv.conf (defaults to /etc/resolv.conf).
-S, --server=/<domain>/<ipaddr>                        Specify address(es) of upstream servers with optional domains.
-s, --domain=<domain>[,<range>]                        Specify the domain to be assigned in DHCP leases.
-t, --mx-target=<host_name>                            Specify default target in an MX record.
-T, --local-ttl=<integer>                              Specify time-to-live in seconds for replies from /etc/hosts.
-u, --user=<username>                                  Change to this user after startup. (defaults to nobody).
-U, --dhcp-vendorclass=set:<tag>,<class>               Map DHCP vendor class to tag.
-v, --version                                          Display dnsmasq version and copyright information.
-V, --alias=<ipaddr>,<ipaddr>,<netmask>                Translate IPv4 addresses from upstream servers.
-W, --srv-host=<name>,<target>,...                     Specify a SRV record.
-w, --help                                             Display this message. Use --help dhcp or --help dhcp6 for known DHCP options.
-x, --pid-file=<path>                                  Specify path of PID file (defaults to /usr/local/var/run/dnsmasq/dnsmasq.pid).
-X, --dhcp-lease-max=<integer>                         Specify maximum number of DHCP leases (defaults to 1000).
-y, --localise-queries                                 Answer DNS queries based on the interface a query was sent to.
-Y, --txt-record=<name>,<txt>[,<txt]                   Specify TXT DNS record.
-z, --bind-interfaces                                  Bind only to interfaces in use.
-Z, --read-ethers                                      Read DHCP static host information from /etc/ethers.

参考サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む