Charles のセットアップ メモ

久しぶりに iOS アプリ開発で Charles を使用したら,セットアップ方法に手間取ったので,メモしておきます.
iOS 10.3 から証明書を信頼する必要があるとのことですが,この手順をきれいさっぱり忘れていて,手間取ったので,メモしておきます.
実機で通信をモニタリングしようとしてうまくいかない方はこの点を確認されることをお勧めします.

▼ Charles でやったこと
・アプリの API リクエスト,レスポンスを確認した
・特定の API リクエストを失敗させて,適切なエラーハンドリングがされていることを確認した(Rewrite 機能)

▼ 設定手順
1. MacにCharlesをインストール
ダウンロードページ
https://www.charlesproxy.com/download/

2. CharlesのSLL Proxyを設定する
Proxy -> SSL Proxy Setting…
Host, Port (443)を設定する

3. MacのIPアドレスを確認する
iPhone に設定するため Charles の Help -> Local IP Address で MacのIPアドレスを確認する
(クラスAの方を適用する?)

4. 実機にSSL証明書をインストール
iPhone に SSL証明書をインストールするため,以下のURLにアクセスする
http://www.charlesproxy.com/getssl

5. 実機のHTTPプロキシを設定
設定 -> Wi-Fi (接続中 Wi-Fi の iマークをタップ) -> (画面最下段の)HTTP プロキシを構成
[手動]を選択し,IPアドレスとポート番号(8888)を入力する

6. 実機で証明書を信頼する
iOS 10.3から証明書の設定項目が追加されている
設定 -> 一般 -> 情報の最下部にある証明書信頼設定で,証明書を信頼する
Charles Proxy CA

ここまで設定すれば,MacのCharlesでiPhoneの通信がモニタリングできるはずです.
(iPhoneでVPNを使用している場合,VPNをオフ)

参考:
最速で作るCharlesのMac環境設定
【開発支援ツール】Charlesの使い方【神ツール】

Xcodeビルド環境を切り替える方法

先日,改修を担当したiOSアプリのXcodeプロジェクト設定が非常にわかりずらいものでした.(PROJECT – Configurations と TARGETS が複数存在し,それらを切り替える Scheme が定義されていなかった)

改めてアプリの参照サーバを切り替える方法など,どのようなプロジェクト設定にしておけば,わかりやすいのか?考えてみたのですが,その際とても参考になった資料をメモしておきます.

参考: [Xcode] ビルド環境を切り替えるためにSchemeを追加する

参考: [Xcode] Xcode 8.0から「Active Compilation Conditions」が追加されて#if, #elseif, #else, #endifによる分岐設定がちょっと楽になってます

プロジェクトの設定項目

PROJECT
Build Settings
Apple Clang - Preprocessing
Preprocessor Macros

設定例:MYDEBUG=1
Swift Compiler - Custom Flags
Active Compilation Conditions

設定例:MYDEBUG
TARGETS
Build Settings
Swift Compiler - Custom Flags
Other Swift Flags

設定例:-D MYDEBUG

ソースコードでは以下のように切り替えることが可能です.

1
2
3
4
5
6
7
8
9
        #if DEBUG
            print("デバッグ環境")
        #elseif STUB
            print("スタブ環境")
        #elseif MYDEBUG
            print("MYDebug環境")
        #else
            print("その他環境")
        #endif

AFNetworkingのリクエストでCookieを扱う方法

先月はSwiftをやっていましたが,今月はObjective-Cです.
数年ぶりに他人が書いたObjective-CでAFNetworkingライブラリを使用した通信処理を読んでいて,Cookieを扱う処理がわからず困ったのでメモしておきます.

▼ AFNetwork でリクエストにCookieを設定する

リクエスト ヘッダにクッキーを設定するには以下のように記述します.

NSString *cookie = [NSString stringWithFormat: @"(Cookieのキー名)=%@; path=/; HttpOnly", (設定する値)];    
[manager.requestSerializer setValue: cookie forHTTPHeaderField: @"Cookie"];        

▼ リクエスト ヘッダを参照する

正しくリクエスト ヘッダにクッキーが設定されているかは,デバッグウィンドウで以下のように参照できます.

(lldb) po manager.requestSerializer.HTTPRequestHeaders

▼ レスポンス ヘッダを参照する

レスポンス ヘッダを参照するには以下のようにレスポンスを受信時に参照できます.

コード省略
	:
success:^(NSURLSessionTask *operation, id responseObject){    
NSHTTPURLResponse *response = (NSHTTPURLResponse *)[operation response];    
 
(lldb) po response.allHeaderFields

▼ レスポンス ヘッダで参照できなかったCookieをCookieストレージで参照する

今回少し困ったことに以下のようにしてもレスポンス ヘッダで参照できるクッキーが参照できなかったので、記事を参考にCookieストレージから参照することで対処しました.

NSString *cookie = httpUrlResponse.allHeaderFields[@"Set-Cookie"];

スタックオーバーフローに参考になる記事がありましたので,メモしておきます.

(参考)How to use AFNetworking to save cookies permanently forever, until the app is deleted from the iPhone?

以下,参考になると思われる部分を抜粋です.

1) Upon successful authentication, the webservice hands me two cookies. 
How do I access them? Do I go straight to NSHTTPCookie storage and grab the cookie by its name, or is there an AFNetworking "way" to do this?

AFNetworking doesn't do anything explicitly with cookies so there is no "AFNetworking way" of dealing with cookies. 
You'll work with NSHTTPCookie and NSHTTPCookieStorage.

【Google翻訳】
1)認証に成功すると、Webサービスは2つのCookieを渡します。それらにアクセスするにはどうすればよいですか? 
NSHTTPCookieストレージに直接移動して、名前でCookieを取得しますか、それともAFNetworkingの「方法」がありますか?

AFNetworkingはCookieを明示的に処理しないため、Cookieを処理する「AFNetworkingの方法」はありません。 
NSHTTPCookieとNSHTTPCookieStorageを使用します。

NSURLSessionでCookieを扱うサンプルは以下が参考になります.
(参考)iOS7:NSURLSessionのhttp(cookie)でハマった

Objective-Cで書かれた通信処理のサンプルを探していて困ったのは,以下のクラスの関係です.
それぞれバージョンアップで改変されたクラスであると理解して情報を参照した方が理解しやすいと思います.

AFHTTPOperationManager → AFHTTPSessionManager
NSURLSession → NSURLConnection

Y!mobileの一括設定でエラーになる場合に確認する項目

ワイモバイルSIMをSIMフリーiPhoneで利用に際して,一括設定するためプロファイルのインストールを行った際にエラーが発生しました.
解決するのに少し苦労したのでメモしておきます.

Y!mobileが提供している資料で【SIMフリースマートフォン 設定ガイド】によると,

Y!mobileメール,ソフトバンクWi-Fiスポット設定などをiPhoneに設定する場合,
一括設定を行うことで,iPhoneに必要な設定をまとめて行うことができます.

とあるので,早速,プロファイルのインストールを行いました.

手順は以下でも紹介されています.
【参照:[iPhone]一括設定の設定方法を教えてください。】

Y!mobileサービスの初期登録完了画面の「一括設定を開始」をタップすることでプロファイルをインストールすることができるのですが,私の場合ここでエラーとなり,プロファイルのインストールが行うことができませんでした.orz

私の場合は,Yahoo! Japanに登録されているメールアドレス情報に現在使用不可メールアドレスが登録されていたためエラーとなっていたようでした.
エラーがでてインストールが完了しない方は,以前にソフトバンク スマートログインなど使用していた方は確認すると良いかもしれません.

ソフトバンクからY!mobile(ワイモバイル)に変更した件

ソフトバンクの料金が高く感じていたので,「SIMフリー端末+ワイモバイルSIM」にMNP乗り換えしました.
その際,手続きで気づいたことをメモしておきます.

私の場合使用したいサービスは以下の通り.

・1ヶ月の通信料は,約10GB程度
・ある程度の通信品質は保証して欲しい
・定額通話プランがある
・iPhone テザリングが無料でできる
・問い合わせサービスは必要ない.

ある程度の品質が担保されるのであれば,適正価格は負担しても良いという考えです.
これの点について,ワイモバイルでサービスが提供されているようであったため,試してみることとしました.

また,ソフトバンクからワイモバイルにMNP乗り換えに際しては,実店舗に出向く必要はありませんでした
全て電話にて手続きすることができました.
ですが,以下の点は注意が必要です.

▼ MNP乗り換え時の注意点

・MNP転出手数料と契約解除料が必要.
・MNP予約番号は発行日を含めて,15日間のみ有効
・2018/10月時点,ワイモバイルからSIMを購入した場合,宅配業者から直接受け取る必要がある.
 (宅配ロッカーでの受取はできない)
・回線切り替え時間が明確でない
・新しい iPhone をアクティベートには通信する必要がある.

▼ ワイモバイルへのMNP乗り換え手続き
手続きの手順は以下の通りです.

1. 新しく使用する端末のSIMロックを解除する.もしくは,新しくSIMフリー端末を購入する
2. MNP予約番号を取得する
3. ワイモバイルでSIMのみを購入する
4. 回線きりかえ,端末のアクティベーション

▼ 1. 新しく使用する端末のSIMロックを解除する

SIMロック解除について調べてみると,

他社へ乗り換え(MNP)または、ワイモバイルへ番号移行(MNP契約)し、ご利用中の携帯電話機器を継続利用される場合は、乗り換え(MNP)や番号移行(MNP契約)の転出手続き前に必ずSIMロック解除を実施してください。
乗り換え(MNP)や番号移行(MNP契約)転出後のSIMロック解除は、ソフトバンクショップのみでのお手続き(有料)となります。

とありますので,事前に使用予定がある端末をSIMロックを解除しておきます.
新しくSIMフリー端末を用意する場合は必要ありませんが,今後も使用する可能性がある iPhone 6S Plus をSIMロック解除しました.
SIMロック解除は実店舗で行うと手数料がかかります.
(SIMロック解除手数料[3,000円])
ですから,無料で手続きできる My SoftBank で手続きした方が良いです.
My SoftBankでのお手続き SIMロック解除手数料[無料]

【参照:ソフトバンクの携帯電話を他社で利用する/SIMロック解除】

【参照:IMEI番号の調べ方】

SIMロック解除の手続き自体はとても簡単です.
ですが,手続き自体が完了しているのか?状態を確認することができないので,その点は少々不安になる点ではあります.
問い合わせにて使用中の端末がロックされているのか?確認することができる場合もあるようですが,あまり気にしなくても良いかもしれません.

【参照:ケータイなんでもサポート窓口】

今回,私は iPhone6S Plus を3年ほど使用していたので,SIMフリー端末を Appleストアにて iPhoneXR を購入しました.
10月末に実店舗で実機を確認してからネットで注文しましたが,5日程度で届きました.

▼ 2. MNP予約番号を取得する

【参照:ソフトバンクからYモバイルへMNPする手続き】

ソフトバンク携帯電話から *5533
受付時間:9:00~20:00

上記の問い合わせ先から MNP予約番号を取得します.

番号に電話してMNP予約番号を発行してもらいます.
ソフトバンクの場合,番号の通知は MMS で届きます.
土曜日の夕方に連絡して,10分程度は待たされました.
最初に目的,MNP予約番号の発行などプッシュ入力します.
担当者からの問いには,基本「YES」と言っておけば,5分程度で番号を発行してもらえます.
メッセージは2通来ますが,タイトルが【MNP予約番号通知】のメッセージのみ参照すればOKです.
重要なことは,予約番号が発行日を含めて15日間のみ有効と言うことです.

当然と言えば当然ですが転出の事業者に 3240 円 が必要です.
あと,転入に際しては事務手数料?が必要な場合があると思います.

▼ 3. ワイモバイルでSIMのみを購入する

ワイモバイル オンラインストアで SIM を購入しました.
→ 音声USIMカードを購入
iPhone XRは,「nanoSIM」です.

配送自体は速やかに行われるようですが,受取に関しては注意が必要です.
宅配ロッカーでは受け取ることができない
ため,場合によっては月曜に届いていても土曜日に受取ということがあるかもしれません.
事前に受取を考慮してスケジューリングしておく必要があります.

一応,新しく使う端末が使えるか?チェックしておきます.

【参照:他社が販売する携帯電話をワイモバイルで利用する】

▼ 4. 回線きりかえ

ワイモバイルの回線切り替えは,商品到着の連絡をもって切り替え作業を行っているようです.
商品到着の翌日切り替えということになり,切り替えの時間が明確でないという点は注意点です.
同じ端末を使い続ける場合は,現キャリアでの通信ができなくなった時点で,SIMのみ入れ替えれば良いですが,新しい端末に切り替える場合などは事前にセットアップを行い,その日は端末を2台持ち歩く必要があります.(笑)

問い合わせにより,切り替え時間を早めてもらう方法もあるようですが,基本的に回線切り替えを考慮して行動する必要があります.
待ち合わせなどは要注意ですね.

また,事前に新しく使用する端末が入手できている場合は,通信プロファイル等の設定は事前に行っておく方が良いと思います.
通信プロファイルのインストールなどは通信環境がないと行えないので,注意点です.
通信環境がない出先で回線が切り替わってしまい,自宅に帰るまでセットアップが行えず,電話が使えなかったという状況も考えられます.(笑)

【参照:[iOS]他社が販売するiPhoneをワイモバイルで利用するにはどうしたらいいですか?】

ワイモバイルオンラインストア事務局
電話番号:0120-200-128
受付時間(当日切替え):10:00~13:00
受付時間(当日切替えまたは翌日切替え):13:00~19:00

【参照:SIMフリースマートフォン 設定ガイド】

【参照:ワイモバイルスマホ 初期設定方法】

これらがMNP乗り換えの手順ですが,新端末のセットアップは思いのほか時間がかかると思います.
私の場合は新しくApplePay,モバイルSuicaの設定を行ったり,通信事業者が提供するプロファイルのインストール時にエラーが発生したりで,予想以上の時間を要しました.
まぁそれはそれで楽しみでもあるのですが…一般的には余計な苦労ですよね.(笑)

iPad Pro 12.9 インチを購入した件

世間は iPhone X で盛り上がっていますが,先日 iPad Pro 12.9 インチをゲットしました.(笑)

今使用している iPad を購入したのが 2012年12月だったので,5年ぶりに新調したことになります.

iPad4 ゲットしました ^_^

iPad4 も寝落ち用 youtube 端末として現役なのですが,マンガの電子書籍端末としてはディスプレイサイズが少し小さく感じていること,Apple Pencil を使用してイラスト制作をしてみたかったので,このたび iPad Pro 12.9 インチを買い足しました.

▼ iOS 11 の自動セットアップ

iOS 11 には自動セットアップという機能があり,すでに使用している iOS 11 端末が手元にある場合,新しく購入した端末に近づけてペアリングすることで,設定を転送することができます.

この機能はあちこちの情報サイトで紹介されていますが,私が iPad Pro の開封時には知らなかったので,ちょっとした驚きでした.

手持ちの iPhone にはこんな画面が表示されます.

そしてこういう感じで端末を近づけろと指示されます.

自動セットアップが完了すれば,そのままネットワーク接続などが行える状態となります.

▼ iPad Pro 費用

費用は以下の通り.

iPad Pro 12.9 インチWi-Fi 256GB 約10万円
Apple Pencil 10,800円
レザー Smart Cover 約9,000円

合計は 約12万円でした.
iPhone X 256GB が 約14万円ほどですので,少し割安感があります.

ちなみにネットのApple Store で注文すると背面に刻印を入れてもらえます.
2017/11 時点で5営業日ほどで入手することができました.

▼ iPad Pro を電子書籍端末として使う

この5年間で iPad の使用用途はほとんど以下のものです.
・youtube
・電子書籍端末

iPad を購入される方の大半は 10.5 インチを選ばれると思いますが,電子書籍,タブレットでの使用を考えて 12.9 インチを選んでみました.

12.9 インチでは,マンガを見開きで閲覧することが可能です.
また,各社から雑誌の読み放題サービスが本格化してきていることなどもあり,これらのサービスの利用を考えた場合,12.9 インチも決して大きすぎることはないと思います.

▼ iPad Pro を液タブとして使う

これを機に iPad をペンタブレットとして使用する方法を考えてみたのですが,
・iPad 用ドローソフトを使用する.
・iPad を Mac の拡張ディスプレイとして,Mac のペイント ソフトを使用する.
などの方法があるようです.

拡張ディスプレイを実現するソフトは以下のものが有名のようです.

Astropad Standard
・液タブ向けの製品
・3,600円

Astropad Studio
・月額 8,00 円 or 年間 7,200 円

参考:Astropad Studio | プロユーザー向けに大進化!iPadをMacの液晶ペンタブに変えるカスタムショートカットや5倍高速描画を実現

とここまで調べた結果,この方法は使えるレベルだけどベストな状態ではないと感じました.

お気に入りアプリの iPad 版を使用することが,やはり最善だと思われますが,手持ちの Mac のグラフィックソフトのタブレット機能を少し試してみたいという程度であれば十分使えるような印象を持ちました.

このあたりは youtube にレビュー動画がいろいろ公開されていますので,実際の使用感,パフォーマンスなどの参考になります.

osx にフォントをコマンドでインストールする方法

Xcode のコードエディタで Swift を書くときに視認性のよいフォントを探したところ,source-code-pro というのが良さそうでした.
しかし,フォントを追加するのは意外に面倒そう.
というわけで簡単にインストールする方法を探したら,ありました.
コマンドラインからインストールできるようだったので,試したところ便利だったのでメモです.

▼ font-source-code-pro をインストールする.

$ brew tap caskroom/fonts                  # you only have to do this once!
$ brew cask install font-source-code-pro

▼ インストールできるフォントのリスト

$ brew cask search /font/


Macにフォントをコマンド一発で導入する!
brew tapとは

Xcode 8.3.2 で Alcatraz が使えなくなった件

Swift の整形ツールを探していて Xcode プラグインがいろいろ出ているようだったので Alcatraz からインストールしようとしたところ,メニューに「プラグイン マネージャ」がなかった.

いろいろ試して,関係はないが Homebrew を使用しようとしたら,Homebrew も利用できない事態になった.最悪だ.

以下の対処方法で Homebrew は使用できるようになった.(ホッ😌)

Homebrewを久々にupdateしたら出来なかった時の対処法
http://qiita.com/takezoux2/items/aa2a5f0bef19cd0d8508

その後,「プラグイン マネージャ」は一度使えるようになったが,再度 Xcode (8.3.2)を起動するとメニューに表示されなくなっていた.プラグインって廃止される傾向なのかなぁー?

Xcode 8 won’t load plug-ins #475
https://github.com/alcatraz/Alcatraz/issues/475

特に困っていないので,そのまま swimat を使用しています.

Swift3, APIKit, ObjectMapper, SnapKit を使って Web API にアクセスしてみた件

最近は,Swift3 で iOS アプリを開発しているのですが,改めて使用しているライブラリについて調べてみた.
仕事では日々実装しなくてはいけないテーマがあり,なかなか全体を俯瞰する機会がないので,GW を期に確認してみたというところです.
ネット上で公開されているライブラリに関する記事をざっとチェックしましたが,公開から1年以上経っていることもあり,なかなかそのままのコードで動作させることが難しいようだったので,個人的なメモとして簡単なコードを書くことにしました.

では早速,サンプルで使用する Web API を選びます.

1. Web API を選ぶ

▼ お天気Webサービス仕様
http://weather.livedoor.com/weather_hacks/webservice
ライブドアで無料提供している Web API のようです.
以下のように「地域ID」を指定することで天気情報を取得できるようです.

(例)「福岡県・久留米の天気」を取得する場合は,以下のURLにアクセスしてJSONデータを取得できるとのこと.
http://weather.livedoor.com/forecast/webservice/json/v1?city=400040

簡単そうなので,これにします.

2. APIKit でリクエスト

Xcode 8.3.2 で Swift3 を使用し,シングルページアプリを作成します.
CocoaPods で,APIKit / ObjectMapper / SnapKit を導入します.

APIKit
https://github.com/ishkawa/APIKit
- iOS 8.0 以降に対応.

ObjectMapper
https://github.com/Hearst-DD/ObjectMapper

SnapKit
http://cocoadocs.org/docsets/SnapKit/0.10.0/index.html
https://github.com/SnapKit/SnapKit

Xcode で作成された ViewController.swift に Web API リクエストのコードを記述します.

1
2
3
4
5
6
7
8
9
10
11
12
private func sendWeatherAPI() {
    let request = WeatherRequest(city: 130010)
    Session.send(request) { [weak self] result in
        switch result {
        case .success(let response):
            self?.dispWetherResponse(dto: response)	// ビューに取得データを表示する
 
        case .failure(let error):
            print("error: \(error)")
        }
    }
}

API リクエストは WeatherRequest という名前にしました.
http://weather.livedoor.com/forecast/webservice/json/v1?city=400040 にアクセするするのでこんな感じでしょう.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import Foundation
import APIKit
import ObjectMapper
 
struct WeatherRequest: Request {
    typealias Response = WeatherResponse
    let city: Int
 
    init(city: Int) {
        self.city = city
    }
    var baseURL: URL {
        return URL(string: "http://weather.livedoor.com/forecast/webservice/json")!
    }
    var method: HTTPMethod {
        return .get
    }
    var path: String {
        return "v1"
    }
    var parameters: Any? {
        return nil
    }
    var queryParameters: [String: Any]? {
        return ["city": city.description]
    }
    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
        guard let object = Mapper<Response>().map(JSONObject: object) else {
            return Response()
        }
        return object
    }
}

3. 取得したデータをマッピング

WebAPI で取得したデータが
func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
に渡されますので,struct にマッピングします.
また,ライブラリのバージョンがあがり,返却するデータの方がオプショナルでなくなっているようです.

とりあえず,3つのデータだけ格納することにします.
階層が一つ下の項目にも map[“description.text”] のようにで参照できるのが便利ですね.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Foundation
import ObjectMapper
 
struct WeatherResponse: Mappable {
    var publicTime = ""
    var title = ""
    var description = ""
 
    init() {
    }
    init?(map: Map) {
    }
 
    mutating func mapping(map: Map) {
        self.publicTime <- map["publicTime"]
        self.title <- map["title"]
        self.description <- map["description.text"]
    }
}

WeatherResponse が,ViewController.swift の Web API リクエスト部分のクロージャー記述に返されるので,画面に表示しておしまいです.

4. SnapKit で制約を指定する

あと,SnapKit で表示用ラベル位置を調整してみます.
SnapKit で制約を指定するわけですが,指定前にビューに対してラベルを addSubview() しておかなくてはなりません.

制約の指定は以下のようにしました.
一度,Autolayout の制約条件を Xcode から行いましたが,大変だった記憶があり,以下のコードだけで制約を指定できるのは大変便利かと思います.

1
2
3
4
5
6
7
8
9
10
titleLabel.snp.makeConstraints { make in
    make.top.equalTo(20)
    make.left.right.equalTo(view).inset(10)
    make.height.equalTo(30)
}
publicTimeLabel.snp.makeConstraints { make in
    make.top.equalTo(titleLabel.snp.bottom)
    make.left.right.equalTo(view).inset(10)
    make.height.equalTo(30)
}

titleLabel の下に publicTimeLabel が配置されるように制約を指定しています.
また,それぞれの高さは 30 です.

簡単にライブラリを使った検証でした.

▼ 追記

Himotoki っていうライブラリも結構紹介されているなぁーー
https://github.com/ikesyo/Himotoki

Swift3.0 正規表現 について

過去の Swift バージョンで記述したコードが Swift3.0 でコンパイルした際に警告を出力していたので書き直した.

簡単に個人的なメモ
– Swift は正規表現は,NSRange などを使用する必要があるため少し面倒.
– 正規表現を扱うには,NSRegularExpression インスタンスを使用する.
– 正規表現の検索結果を参照する必要がある場合,regex.matches を参照する.
– String クラスの characters.count は文字列の文字を,全角半角関係なく1文字と数える.
– NSString クラスの length は,全角文字を半角文字2文字分として数える.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import Foundation
extension String {
    var count: Int {
        let string_NS = self as NSString
        return string_NS.length
    }
 
    // 正規表現で検索する.
    // .caseInsensitive 大文字小文字の区別を無視する
    func pregMatche(pattern: String, options: NSRegularExpression.Options = [.caseInsensitive]) -> Bool {
        guard let regex = try? NSRegularExpression(pattern: pattern, options: options) else {
            return false
        }
        let matches = regex.matches(in: self, options: [], range: NSMakeRange(0, self.count))
        return matches.count > 0
    }
 
    // 正規表現で検索する.(検索結果を使用)
    func pregMatche(pattern: String, options: NSRegularExpression.Options = [.caseInsensitive], matches: inout [String]) -> Bool {
        guard let regex = try? NSRegularExpression(pattern: pattern, options: options) else {
            return false
        }
        let targetStringRange = NSRange(location: 0, length: self.count)
        let results = regex.matches(in: self, options: [], range: targetStringRange)
        for i in 0 ..< results.count {
            for j in 0 ..< results[i].numberOfRanges {
                let range = results[i].rangeAt(j)
                matches.append((self as NSString).substring(with: range))
            }
        }
        return results.count > 0
    }
}