20210414のiOSに関する記事は8件です。

楽してAndroid/iOSアプリ個人開発

はじめに どうも、@nittannittanです。 趣味でAndroid/iOS/Webアプリを作成しているアニメオタクです。 今まではAndroid/iOSアプリはそれぞれJava, Kotlin, Objective-c, Swiftなどの言語でそれぞれ開発していました。 しかし、どちらか一方を開発して公開したあとにまた同じようなことを繰り返すのは勉強にはなりますが、仕事の合間にやる個人開発ではあまり楽ではないなーと感じていました。 そこで「最近マルチプラットフォームも流行ってきているようだし、そろそろ本腰を入れてみるかー」という軽い気持ちからFlutterでAndroid/iOSアプリを同時開発することにしました。 Flutterを選んだ理由 Googleが開発しているからまずAndroidは間違いなく相性は良いだろうし、個人開発でFirebaseを使わないわけがないので、Flutterを採用しました。WebアプリでReact使っているわけでもないし、iOS版に対応していなかった時代を知っているのでReact Nativeは今回はやめました。 ReactでWeb開発してたらReact Nativeを選んだのかもしれません。 参考にしたサイト まずはDartを知る必要があるため言語の公式ドキュメントをさらっと読みました。深くは読み込みません、私のやり方的に実際に手を動かして覚えるほうがやりやすくてわからなくなった時に再度読みます。手を動かさないとモチベーション維持も難しいですし、個人開発だとやる気が下がったらおしまいですからね。 ぱっとソースを見た時に全然わからないと投げ出しそうになったUIの構築方法も公式のドキュメントを見たらあっさり理解できました。慣れたらxmlやStoryboardでUIを作るのが面倒に思えてきます。特にStoryboardはgitでの差分確認がよっぽどの超人じゃないとできないですしね。 私が作ろうとしていたアプリはTODOアプリの作り方が参考にできそうだったので下記を見ながらベースを作りました。 利用パッケージの参考にしたのは下記。 最終的に利用したパッケージ pubspec.yaml dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.0 # MVVMで作るのに利用 provider: ^4.3.3 # データベースにデータ保存するのに利用 moor: ^4.1.0 sqlite3_flutter_libs: # Also use the latest version. path_provider: path: # アイコンを表示するのに利用 flutter_icons: ^1.1.0 # ダイアログの見栄えを良くするのに利用 awesome_dialog: ^1.3.2 # アプリからブラウザを開くために利用 url_launcher: ^6.0.3 # 必要なアプリアイコンを自動生成するのに利用 flutter_launcher_icons: ^0.9.0 # スプラッシュ画面を自動生成するために利用 flutter_native_splash: ^1.1.5+1 # Firebase関連 firebase_core: ^1.0.2 firebase_analytics: ^7.1.1 firebase_crashlytics: ^1.0.0 firebase_auth: ^1.0.3 google_sign_in: ^5.0.1 # GoogleDriveにバックアップファイルを保存するのに利用 googleapis: ^2.0.0 楽したポイント moor AndroidとiOSで差が出やすかったデータベースへのデータ保存もパッケージを利用することで簡単に対応できました。何も悩まずにマルチプラットフォームでデータ保存が実現できたのは衝撃的でした。 awesome_dialog 参考サイトでも紹介されていたパッケージですが、こちらも少ない工数でダイアログの見栄えが劇的に良くなるのでおすすめです。 flutter_launcher_icons iOSアプリをApp Storeに公開したことがある人ならわかると思いますが、iOSアプリは用意しなければならないアプリアイコンの数がとても多いです。それを画像一つ用意するだけで自動設定できるのはまたまた衝撃的でした。Androidのアダプティブアイコンにも対応しているのでかゆいところに手が届きます。 flutter_native_splash このパッケージもスプラッシュ画面が画像一つで表示できるようにできるのでとても楽ができます。 開発したトラウマ解消アプリの紹介 トラウマ解消アプリは、ふとした瞬間にフラッシュバックするトラウマを認知行動療法によって解消するためのアプリです。 使い方は以下です。 まずは、トラウマがフラッシュバックした時にそのトラウマに名前をつけて保存しましょう。 フラッシュバックした時に詳細な情報まで記録できるとは限らないと思います。名前以外の詳細は時間があるときにゆっくり書き出しましょう。 トラウマに名前をつけたり、詳細を書き出すことによって客観的に考えを整理することができ決めつけでネガティブになっていたことに気がついたり、バランスがいい考え方ができるようになります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】【UITableView】セクションに行がない??

概要 TableViewを用いた時にハマったエラー なかなか原因がわからなかったので備忘録です エラー "attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update" ビルドしようとするとこのエラーが出てくる TableViewに行を作ろうとしたがセクションに行がなくてクラッシュしたらしい 解決法 TableViewを構築する時の numberOfRowsInSectionが numberOfSectionsになっていただけでしためちゃ簡単だった override func numberOfSections(in tableView: UITableView) -> Int { //code } ↓ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { //code } コード補完で出てきてミスったっぽい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

StrongSwanにiPhoneからオレオレ証明書認証でIPsec IKEv2を繋げる

はじめに iOSでIKEv2が使えるようになっているのですが、パスワード認証の話が多くて証明書による認証について書いてあるところがあまりないので、まとめておきます。 目的 以下の環境での接続を目指します。 サーバ Ubuntu 18.04 LTS StrongSwan (swanctl) オレオレサーバ証明書 クランアント iPhone (iOS 14) オレオレクライアント証明書 使用プロトコルと認証方法 IKEv2 クライアント証明書認証(パスワードなし) 凡例 この文章では以下のようになっているものとします。 ドメイン名: exmaple.com サーバホスト名: servername.example.com サーバアドレス: 198.51.100.1 (DNS登録済み) クライアント名: iphone クライアントに割り当てる仮想IP: 203.0.113.0/24 クライアント用DNSサーバ: 198.51.100.2 オレオレ証明書の名前: strongswan-ca.example.com 説明上ここではIPv4しか使っていませんが、IPv6も使えます。,で区切ってIPv4アドレスの後ろに繋げればOKです。 ハマりどころ 試行錯誤の結果、以下に気をつけると繋がりました。 証明書はRSAではなくECDSAにする 以下のバグのためStrongSwanはRSA証明書での検証ではSHA1しか使えないのですが、iOSはRSA証明書についてはSHA2を使うようです。 そこで、クライアント側もサーバ側もECDSAを使うことでこの問題を回避します。 Issue #3343: signature validation failed, looking for another key - strongSwan 証明書のCN, SAN, EKU iOSにいれるクライアント証明書は、 CN, SANともにiphone@example.com や iphone.example.com の形式ではなく iphone にする EKUはclientAuth StrongSwanにいれるサーバ側の証明書は、 CN, SANともにservername.example.com にする EKUはserverAuth となります。 IKEv2 で接続できた各OSの認証方式とクライアント証明書 | KUSONEKOの見る世界 オレオレCAのルート証明書をいれて信頼する必要がある 後述のmobileconfigに同梱すればIKEv2接続時だけ勝手に信頼してくれるのかと思ったのですが、そうではありませんでした。 mobileconfigとは別にオレオレCAのルート証明書もいれて設定 - 一般 - 情報 - 証明書信頼設定 から全面的信頼をつける必要があります。 スマートフォン(iOS、Android)にオレオレ証明書がインストールできない? | 世界一わかりやすいセキュリティ mobileconfig 「証明書のタイプ」はECDSA521など正しい値を選択する(ECDSAなのにRSAのままにしない) 「EAPを使用する」はチェックしない iOS (Apple iPhone/iPad...) and macOS Interoperability - iOS (Apple iPhone/iPad...) and macOS Interoperability - strongSwan 証明書作成 こちらに掲載のスクリプトを修正して使いました。感謝。 strongSwanでVPN (IKEv2)を構築する - Qiita CA生成 一回だけ実行します。 initca.sh #!/bin/bash set -x set -e #各種 key,crt,サーバードメインを埋めて実行します。 #ファイル名 readonly CA_NAME=strongswan-ca readonly DOMAIN=example.com readonly OUTPATH=$HOME/strongswan/pki/certs/ readonly CA_KEY=$CA_NAME.key readonly CA_CRT=$CA_NAME.crt #初期化 rm -fr $OUTPATH mkdir $OUTPATH LIFETIME="--lifetime 3650" #ルート証明書作成 cakey=${OUTPATH}/${CA_KEY} cacrt=${OUTPATH}/${CA_CRT} ipsec pki --gen $OPTS > $cakey ipsec pki --self --in $cakey $LIFETIME --ca --dn "C=JP, O=strongSwan, CN=${CA_NAME}.${DOMAIN}" --san "${CA_NAME}.${DOMAIN}" > $cacrt #確認 openssl x509 -text -fingerprint -noout -inform der -in $cacrt #pem openssl x509 -inform der -outform pem -in $cacrt > ${OUTPATH}/${CA_NAME}.pem etckey=/etc/swanctl/ecdsa/$CA_KEY etccrt=/etc/swanctl/x509ca/$CA_CRT sudo cp $cakey $etckey sudo cp $cacrt $etccrt sudo chmod 600 $etckey $etccrt sudo chown root:root $etckey $etccrt サーバ証明書生成 genserver.sh #!/bin/bash set -x set -e readonly HOST_NAME=$1 [ -z "$HOST_NAME" ] && no_host_name readonly CA_NAME=strongswan-ca readonly DOMAIN=example.com readonly P12PASS=opensesame readonly OUTPATH=$HOME/strongswan/pki/certs/ readonly CA_KEY=$CA_NAME.key readonly CA_CRT=$CA_NAME.crt readonly SRV_DOMAIN=example.com readonly VPN_KEY=$HOST_NAME.key readonly VPN_CRT=$HOST_NAME.crt cakey=${OUTPATH}/${CA_KEY} cacrt=${OUTPATH}/${CA_CRT} srvkey=${OUTPATH}/${VPN_KEY} srvcrt=${OUTPATH}/${VPN_CRT} OPTS="--type ecdsa --size 521" TYPE=ecdsa TYPE_O=ec #OPTS="--type rsa --size 4096" #TYPE=rsa #TYPE_O=rsa LIFETIME="--lifetime 3650" [ -e $srvkey ] && already_exists ipsec pki --gen $OPTS > $srvkey if [[ $0 =~ server ]] ;then echo server FLAGS="--flag serverAuth" SAN="${HOST_NAME}.${SRV_DOMAIN}" elif [[ $0 =~ name ]] ;then # ios用 FLAGS="--flag clientAuth" SAN="${HOST_NAME}" elif [[ $0 =~ client ]] ;then # macos他普通のクライアント用 FLAGS="--flag clientAuth" SAN="${HOST_NAME}@${SRV_DOMAIN}" fi ipsec pki --issue $LIFETIME $FLAGS \ --in $srvkey --type priv --cacert $cacrt --cakey $cakey \ --flag serverAuth \ --dn "C=JP, O=strongSwan, CN=${SAN}" \ --san ${SAN} > $srvcrt #確認 openssl x509 -text -fingerprint -noout -inform der -in $srvcrt etckey=/etc/swanctl/$TYPE/$VPN_KEY etccrt=/etc/swanctl/x509/$VPN_CRT sudo cp $srvkey $etckey sudo cp $srvcrt $etccrt sudo chmod 600 $etckey $etccrt sudo chown root:root $etckey $etccrt #p12 p12=${OUTPATH}/${HOST_NAME}.p12 ca_cert_pem=$(tempfile).pem srv_cert_pem=$(tempfile).pem srv_key_pem=$(tempfile).pem openssl x509 -inform der -outform pem -in $cacrt -out $ca_cert_pem openssl x509 -inform der -outform pem -in $srvcrt -out $srv_cert_pem openssl $TYPE_O -inform der -outform pem -in $srvkey -out $srv_key_pem openssl pkcs12 -export -passout pass:$P12PASS -inkey $srv_key_pem -in $srv_cert_pem -certfile $ca_cert_pem -out $p12 rm $ca_cert_pem $srv_cert_pem $srv_key_pem これを実行します。 $ ./genserver.sh servername クライアント証明書生成 上記スクリプトをgennameshにln -sして実行します。 $ ln -s genserver.sh genname.sh $ ./genname.sh iphone StrongSwan (swanctl) の設定 /etc/swanctl/conf.d/iphone.conf connections { iphone { local_addrs = 198.51.100.1 proposals = aes256-sha256-modp2048 local { auth = pubkey certs = servername.crt id = servername.exmaple.com } remote { auth = pubkey id = iphone } pools = iphone-pool children { iphone { local_ts = 0.0.0.0/0,::/0 remote_ts = 203.0.113.0/24 esp_proposals = aes256-sha256 } } encap = yes send_certreq = no send_cert = always keyingtries = 10 version = 2 mobike = yes reauth_time = 0 } } pools { iphone-pool { addrs = 203.0.113.0/24 dns = 198.51.100.2 } } iPhoneの設定 Apple Configurator 2を使ってmobileconfigを生成します。 証明書 genname.shで生成したPKCS12をいれる VPN 接続のタイプ: IKEv2 サーバ: servername.exmaple.com リモート識別子: servername.example.com ローカル識別子: iphone コンピュータ認証: 証明書 固有名証明書: 上記の追加したPKCS12を選択 証明書のタイプ: ECDSA521 EAPを有効にする: チェックしない 暗号化アルゴリズム: AES-256 整合性アルゴリズム: SHA2-256 作ったら安全にiPhoneに転送してプロファイルとして取り込みます。 それとは別に、initca.shが生成してくれたstrongswan-ca.pem もいれて、設定 - 一般 - 情報 - 証明書信頼設定 から全面的信頼をつけます。 参考: macOSの場合 $ ln -s genserver.sh genclient.sh $ ./genclient.sh mac としてmac.p12を生成してキーチェーンに取り込み、やはりルート証明書として強制的に信頼させたあと、環境設定 - ネットワークから以下の条件でVPNを設定します。 VPNタイプ: IKEv2 サーバアドレス: servername.example.com リモートID: servername.exmample.com ローカルID: mac@example.com 認証設定: 証明書 (mac@example.comの証明書を選択) その他 NSAのバックドアが無いであろうchacha20-poly1305も使えるそうです。 iPhone側はAESをハードウェアで処理できるそうですので、もしかしたらAESの方がバッテリーには優しいかもしれません(未確認)。 strongSwan と iOS (13+) 端末間で IKEv2 に ChaCha20-Poly1305 を使って遅いラズパイ VPN サーバーを高速化 - Qiita 謝辞 StrongSwanの製作者、リンク先の記事の筆者の皆様、ありがとうございます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

strongSwanにiPhoneからオレオレ証明書認証でIPsec IKEv2を繋げる

はじめに iOSでIKEv2が使えるようになっているのですが、パスワード認証の話が多くて証明書による認証について書いてあるところがあまりないので、まとめておきます。 目的 以下の環境での接続を目指します。 サーバ Ubuntu 18.04 strongSwan (swanctl) オレオレサーバ証明書 クランアント iPhone (iOS 14) オレオレクライアント証明書 使用プロトコルと認証方法 IKEv2 クライアント証明書認証(パスワードなし) 凡例 この文章では以下のようになっているものとします。 ドメイン名: exmaple.com サーバホスト名: servername.example.com サーバアドレス: 198.51.100.1 (DNS登録済み) クライアント名: iphone クライアントに割り当てる仮想IP: 203.0.113.0/24 クライアント用DNSサーバ: 198.51.100.2 オレオレ証明書の名前: strongswan-ca.example.com 説明上ここではIPv4しか使っていませんが、IPv6も使えます。,で区切ってIPv4アドレスの後ろに繋げればOKです。 ハマりどころ 試行錯誤の結果、以下に気をつけると繋がりました。 証明書はRSAではなくECDSAにする 以下のバグのためstrongSwanはRSA証明書での検証ではSHA1しか使えないのですが、iOSはRSA証明書についてはSHA2を使うようです(というかIKEv2のRFCにはSHA2を使えと書いてある)。 そこで、クライアント側もサーバ側もECDSAを使うことでこの問題を回避します。 Issue #3343: signature validation failed, looking for another key - strongSwan 証明書のCN, SAN, EKU iOSにいれるクライアント証明書は、 CN, SANともにiphone@example.com や iphone.example.com の形式ではなく iphone にする EKUはclientAuth strongSwanにいれるサーバ側の証明書は、 CN, SANともにservername.example.com にする EKUはserverAuth となります。 IKEv2 で接続できた各OSの認証方式とクライアント証明書 | KUSONEKOの見る世界 オレオレCAのルート証明書をいれて信頼する必要がある 後述のmobileconfigに同梱すればIKEv2接続時だけ勝手に信頼してくれるのかと思ったのですが、そうではありませんでした。 mobileconfigとは別にオレオレCAのルート証明書もいれて設定 - 一般 - 情報 - 証明書信頼設定 から全面的信頼をつける必要があります。 スマートフォン(iOS、Android)にオレオレ証明書がインストールできない? | 世界一わかりやすいセキュリティ mobileconfig 「証明書のタイプ」はECDSA521など正しい値を選択する(ECDSAなのにRSAのままにしない) 「EAPを使用する」はチェックしない EAPを頑張ったのですがどうもうまくいきませんでした... IKEv2 Configuration Profile for Apple iOS 8 and newer - IKEv2 Configuration Profile for Apple iOS 8 and newer - strongSwan iOS (Apple iPhone/iPad...) and macOS Interoperability - iOS (Apple iPhone/iPad...) and macOS Interoperability - strongSwan 証明書作成 こちらに掲載のスクリプトを修正して使いました。感謝。 strongSwanでVPN (IKEv2)を構築する - Qiita CA生成 一回だけ実行します。 initca.sh #!/bin/bash set -x set -e #各種 key,crt,サーバードメインを埋めて実行します。 #ファイル名 readonly CA_NAME=strongswan-ca readonly DOMAIN=example.com readonly OUTPATH=$HOME/strongswan/pki/certs/ readonly CA_KEY=$CA_NAME.key readonly CA_CRT=$CA_NAME.crt #初期化 rm -fr $OUTPATH mkdir $OUTPATH LIFETIME="--lifetime 3650" #ルート証明書作成 cakey=${OUTPATH}/${CA_KEY} cacrt=${OUTPATH}/${CA_CRT} ipsec pki --gen $OPTS > $cakey ipsec pki --self --in $cakey $LIFETIME --ca --dn "C=JP, O=strongSwan, CN=${CA_NAME}.${DOMAIN}" --san "${CA_NAME}.${DOMAIN}" > $cacrt #確認 openssl x509 -text -fingerprint -noout -inform der -in $cacrt #pem openssl x509 -inform der -outform pem -in $cacrt > ${OUTPATH}/${CA_NAME}.pem etckey=/etc/swanctl/ecdsa/$CA_KEY etccrt=/etc/swanctl/x509ca/$CA_CRT sudo cp $cakey $etckey sudo cp $cacrt $etccrt sudo chmod 600 $etckey $etccrt sudo chown root:root $etckey $etccrt サーバ証明書生成 genserver.sh #!/bin/bash set -x set -e readonly HOST_NAME=$1 [ -z "$HOST_NAME" ] && no_host_name readonly CA_NAME=strongswan-ca readonly DOMAIN=example.com readonly P12PASS=opensesame readonly OUTPATH=$HOME/strongswan/pki/certs/ readonly CA_KEY=$CA_NAME.key readonly CA_CRT=$CA_NAME.crt readonly SRV_DOMAIN=example.com readonly VPN_KEY=$HOST_NAME.key readonly VPN_CRT=$HOST_NAME.crt cakey=${OUTPATH}/${CA_KEY} cacrt=${OUTPATH}/${CA_CRT} srvkey=${OUTPATH}/${VPN_KEY} srvcrt=${OUTPATH}/${VPN_CRT} OPTS="--type ecdsa --size 521" TYPE=ecdsa TYPE_O=ec #OPTS="--type rsa --size 4096" #TYPE=rsa #TYPE_O=rsa LIFETIME="--lifetime 3650" [ -e $srvkey ] && already_exists ipsec pki --gen $OPTS > $srvkey if [[ $0 =~ server ]] ;then echo server FLAGS="--flag serverAuth" SAN="${HOST_NAME}.${SRV_DOMAIN}" elif [[ $0 =~ name ]] ;then # ios用 FLAGS="--flag clientAuth" SAN="${HOST_NAME}" elif [[ $0 =~ client ]] ;then # macos他普通のクライアント用 FLAGS="--flag clientAuth" SAN="${HOST_NAME}@${SRV_DOMAIN}" fi ipsec pki --issue $LIFETIME $FLAGS \ --in $srvkey --type priv --cacert $cacrt --cakey $cakey \ --flag serverAuth \ --dn "C=JP, O=strongSwan, CN=${SAN}" \ --san ${SAN} > $srvcrt #確認 openssl x509 -text -fingerprint -noout -inform der -in $srvcrt etckey=/etc/swanctl/$TYPE/$VPN_KEY etccrt=/etc/swanctl/x509/$VPN_CRT sudo cp $srvkey $etckey sudo cp $srvcrt $etccrt sudo chmod 600 $etckey $etccrt sudo chown root:root $etckey $etccrt #p12 p12=${OUTPATH}/${HOST_NAME}.p12 ca_cert_pem=$(tempfile).pem srv_cert_pem=$(tempfile).pem srv_key_pem=$(tempfile).pem openssl x509 -inform der -outform pem -in $cacrt -out $ca_cert_pem openssl x509 -inform der -outform pem -in $srvcrt -out $srv_cert_pem openssl $TYPE_O -inform der -outform pem -in $srvkey -out $srv_key_pem openssl pkcs12 -export -passout pass:$P12PASS -inkey $srv_key_pem -in $srv_cert_pem -certfile $ca_cert_pem -out $p12 rm $ca_cert_pem $srv_cert_pem $srv_key_pem これを実行します。 $ ./genserver.sh servername クライアント証明書生成 上記スクリプトをgennameshにln -sして実行します。 $ ln -s genserver.sh genname.sh $ ./genname.sh iphone StrongSwan (swanctl) の設定 /etc/swanctl/conf.d/iphone.conf connections { iphone { local_addrs = 198.51.100.1 proposals = aes256-sha256-modp2048 local { auth = pubkey certs = servername.crt id = servername.exmaple.com } remote { auth = pubkey id = iphone } pools = iphone-pool children { iphone { local_ts = 0.0.0.0/0,::/0 remote_ts = 203.0.113.0/24 esp_proposals = aes256-sha256 } } encap = yes send_certreq = no send_cert = always keyingtries = 10 version = 2 mobike = yes reauth_time = 0 } } pools { iphone-pool { addrs = 203.0.113.0/24 dns = 198.51.100.2 } } iPhoneの設定 Apple Configurator 2を使ってmobileconfigを生成します。 証明書 genname.shで生成したPKCS12をいれる VPN 接続のタイプ: IKEv2 サーバ: servername.exmaple.com リモート識別子: servername.example.com ローカル識別子: iphone コンピュータ認証: 証明書 固有名証明書: 上記の追加したPKCS12を選択 証明書のタイプ: ECDSA521 EAPを有効にする: チェックしない 暗号化アルゴリズム: AES-256 整合性アルゴリズム: SHA2-256 作ったら安全にiPhoneに転送してプロファイルとして取り込みます。 それとは別に、initca.shが生成してくれたstrongswan-ca.pem もいれて、設定 - 一般 - 情報 - 証明書信頼設定 から全面的信頼をつけます。 参考: macOSの場合 $ ln -s genserver.sh genclient.sh $ ./genclient.sh mac としてmac.p12を生成してキーチェーンに取り込み、やはりルート証明書として強制的に信頼させたあと、環境設定 - ネットワークから以下の条件でVPNを設定します。 VPNタイプ: IKEv2 サーバアドレス: servername.example.com リモートID: servername.exmample.com ローカルID: mac@example.com 認証設定: 証明書 (mac@example.comの証明書を選択) ChaCha20-Poly1305 高速でNSAのバックドアが無いであろうchacha20-poly1305も使えます。 iPhone側はAESをハードウェアで処理できるそうですので、もしかしたらAESの方がバッテリーには優しいかもしれませんが... strongSwan と iOS (13+) 端末間で IKEv2 に ChaCha20-Poly1305 を使って遅いラズパイ VPN サーバーを高速化 - Qiita 一つだけ問題がありまして、Ubuntu 18.04のstrongSwan 5.6.2にはchacah20poly1305回りにバグがあり、そのままではつながりません。 以下のチケットに記載のパッチをあてるか、5.6.3以上を入れる必要があります。 Issue #3195: chacha20poly1305 cipher name mismatch on proposals - strongSwan 謝辞 strongSwanの製作者、リンク先の記事の筆者の皆様、ありがとうございます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

xcrun: error: unable to find utility "altool", not a developer tool or in PATHの解決法

Command Line Toolsがエラー App Store Connectなんかにビルドをアップロードする時なんかに使う人もいるであろうxcrun altoolのコマンド。 xcrun altool --upload-app -f aaaaaaaaaaa.ipa -t ios -u test@gmail.com -p testtest こんな感じのコマンドでビルドをテストフライトにアップしようとしたらエラー発生!!! xcrun: error: unable to find utility "altool", not a developer tool or in PATH よくわからんが再度インストールしようとしても、ダメらしい。。。 xcode-select --install xcode-select: error: command line tools are already installed, use "Software Update" to install updates CommandLineToolsを削除して再インストール sudo rm -rf /Library/Developer/CommandLineTools xcode-select --install 上記のコマンドで無事解決しました。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UISplitViewControllerの優良サンプルソースコード

UISplitViewControllerの、わかりやすいサンプルソースコードに、なかなか辿りつかなかったので、自分用メモなリンクを共有しておきます。 記事 UISplit​View​Controller https://nshipster.com/uisplitviewcontroller/ ソース https://github.com/NSHipster/UISplitViewController-Example
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】RxSwiftをTwitterで知り合った人に教えてもらったPart2

はじめに 前回 今回も教えていただいたことをまとめていこうと思います。 実装 ViewController import UIKit import RxSwift import RxCocoa final class ViewController: UIViewController { @IBOutlet private weak var textField: UITextField! @IBOutlet private weak var button: UIButton! @IBOutlet private weak var label: UILabel! private let disposeBag = DisposeBag() private var viewModel: ViewModelType = ViewModel() override func viewDidLoad() { super.viewDidLoad() // MARK: - Input //bindでViewModelにイベントを送るパターン textField.rx.text.orEmpty .bind(to: viewModel.inputs.text) .disposed(by: disposeBag) //onNextで送るパターン button.rx.tap .subscribe { _ in self.viewModel.inputs.text.onNext("タップ") } .disposed(by: disposeBag) // MARK: - Output //viewModelからoutputをUIパーツにbindするパターン viewModel.outputs.validText .bind(to: label.rx.text) .disposed(by: disposeBag) } } ViewModel import RxSwift import RxCocoa protocol ViewModelInput { //読み取り専用にしたいため、AnyObserver var text: AnyObserver<String> { get } } protocol ViewModelOutput { //ViewでsubsrcibeするためにObservable var validText: Observable<String> { get } } protocol ViewModelType { var inputs: ViewModelInput { get } var outputs: ViewModelOutput { get } } class ViewModel: ViewModelInput, ViewModelOutput { var text: AnyObserver<String> var validText: Observable<String> init() { let _validText = PublishRelay<String>() self.validText = _validText.asObservable() self.text = AnyObserver<String>() { text in //viewからイベントを受け取り、加工したものをoutputにaccept let validText = text.element! _validText.accept(validText) } } } extension ViewModel: ViewModelType { var inputs: ViewModelInput { return self } var outputs: ViewModelOutput { return self } } イベントの送り方受け取り方 Input(View -> ViewModel) 今回はボタンを押した時とテキストフィールドに文字が入力された時にイベントを流します。 以下はbindでviewModelのinputのtextにイベントを送っています。 textField.rx.text.orEmpty .bind(to: viewModel.inputs.text) .disposed(by: disposeBag) こちらはボタンのイベントをviewModelのinputのtextにonNextで送っています。 button.rx.tap .subscribe { _ in self.viewModel.inputs.text.onNext("タップ") } .disposed(by: disposeBag) そして、ViewModelのViewModelInputプロトコルに送るtextを定義しておいて、加工してoutputで返すという流れです。 protocol ViewModelInput { var text: AnyObserver<String> { get } } Output(ViewModel -> View) イニシャライザ内で値を加工し、acceptでoutputにイベントを送ります。 class ViewModel: ViewModelInput, ViewModelOutput { var text: AnyObserver<String> var validText: Observable<String> init() { let _validText = PublishRelay<String>() self.validText = _validText.asObservable() self.text = AnyObserver<String>() { text in let validText = text.element! _validText.accept(validText) } } } viewModelから送られてきたoutputをbindすることで、labelに反映させる。 viewModel.outputs.validText .bind(to: label.rx.text) .disposed(by: disposeBag) おわりに 少しずつ分かってきましたね!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UIButtonの画像をアスペクト比を維持してサイズ変更

はじめに UIButtonのサイズ変更に伴い,内部の画像サイズを変更したい場合の方法についてメモしました. 拡大方法 UIButtonいっぱいに画像を拡大. button.imageView?.contentMode = .scaleAspectFit button.contentHorizontalAlignment = .fill // オリジナルの画像サイズを超えて拡大(水平) button.contentVerticalAlignment = .fill // オリジナルの画像サイズを超えて拡大(垂直) 縮小方法 画像の上下左右にマージンを取ることで縮小. button.imageEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) 参考 iOS UIButtonの画像の比率を固定して拡縮する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む