2018年10月1日月曜日

Xcode10でビルドが通らない

毎度おなじみ
linker command failed with exit code 1 (use -v to see invocation)
が出ます。
~/Library/Developer/Xcode/DerivedDataを削除すると、大方のプロジェクトは治りましたが、c++のライブラリを使っているものが、治りません。

これは、Apple Developer Forumsで議論されていました。

Xcode 10 beta 4 - stdlibc++ headers not found;

簡単にいうと、Xcode10から libstdc++がなくなっちゃったということです。

仕方がないので、Xcode9にあったヘッダーとライブラリをコピーしました。

最終的にはlibc++に切り替えることが望ましいということなんだろうけど、
Podsで引き込んだライブラリをlibc++で使えるようにするのは、面倒なのでしばらく保留ですね。


AWSにメールサーバを立てる


1.Route53での設定


ドメインネームは取得済(購入済)で、運用中のものがあるものとします。
その前提で、今回はサブドメインを作成し、それをRoute53に登録しました。


もちろん運用中のDNSサーバにも、なんらかの設定が必要です。
私の場合DNSサーバはオンプレミスで運用しており、bind8での設定追加となりました(AWSではないので詳細略)。

で、話はRoute53に戻りますが、メール受信にはMXレコードが必要です。
が、それは手動で追加しなくても、次のSESで設定すればRoute53に自動反映されます。
ですので、Route53の設定はこれでおしまいです。

2.SESでの設定


現状東京リージョンには存在しないので、アメリカのリージョンでの作業になります。
(このことが後々まで面倒を引き起こすのですが…)
Domainsには既にRoute53で設定したものが存在しているので、もうメールは受信できる状態です。
後は受信した時にどうしたいかをRule Setで登録します。
ここではLambdaで受けるものとして、話をすすめます。



3.Lambdaの作成


例えばこんな感じです。



4.CloudWatchでメールの受信を確認


Lambdaが吐いたログは、CloudWatchのログで確認できます。

実験としてはこれでおしまいでいいのですが、実務としてはこれからが問題です。
私の場合、東京リージョンにあるRDSにメールの本文を登録したいのですが、これが簡単ではありませんでした。

5.SNSで東京リージョンに飛ばす


「アメリカのSES⇒アメリカのLambda」では、アメリカのVPC(EC2, RDS...)にしかアクセスできないので、東京のLambdaに接続することが必要になります。
このためには、現状SNSを挟むしかないようです。
「アメリカのSES⇒アメリカのSNS⇒東京のLambda」

【処方箋】
1.アメリカのSNSでトピックを作成。
  実メールアドレスと結びつける必要はないので、これでおしまい。
  サブスクリプションのエンドポイントには、Lambdaとの結合後に、自動的に値が反映される。
2.東京のLambdaでトリガーとしてSNSを選択。
  arnの選択肢には、前項のアメリカのSNSは出てこないで、コピペでarnを打ち込む必要あり。

ちなみにS3を介在させる案「アメリカのSES⇒アメリカのLambda⇒S3⇒東京のLambda」も模索しましたが、出来ませんでした。

6.RDSにはどうやってアクセスするの?


Lambda⇒DynamoDBはできるらしいですが、RDSにアクセスするのはいろいろと障壁がありました。
まず、Lambdaでどの(プログラム言語の)ランタイムを選択したかに大きく依存します。
そのランタイムが、データベースへアクセスするライブラリを標準で持っているかが問題となり、標準で持っていない場合には、デプロイといわれる作業で、ライブラリをインストールする必要があります。

私の場合は、Node.js(javascript)を選択し、RDSはOracleだったので、oracledbというライブラリをデプロイしました。
しかし、結果はご覧の通りで、動きませんでした。

module initialization error: Error
Cannot load /var/task/node_modules/oracledb/build/Release/oracledb.node
/var/task/node_modules/oracledb/build/Release/oracledb.node: invalid ELF header
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
You must have 64-bit Oracle client libraries in LD_LIBRARY_PATH, or configured with ldconfig.
If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from 
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

at Object.<anonymous> (/var/task/node_modules/oracledb/lib/oracledb.js:68:13)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/var/task/node_modules/oracledb/index.js:1:80)
at Module._compile (module.js:570:32)

Node.jsが動いているlinuxにnode-oracledbをインストールすれということでしょうか?
無茶なことをいいます。
しかし解決された方はいらっしゃるようです。
AWS Lambda (Node.js-v4.3.2)からOracleに接続する(ORA-21561への対応)

7.別な方法でRDSへアクセス


そもそもインラインで気軽に書けるということでNode.jsを選択した私なので、Node.jsゆえに苦労をするのはまっぴら御免。というわけで、node-oracledbの導入は諦めました。
現在EC2上で運用中のtomcatサーブレットに、Lambdaから必要なデータを渡すことにしました。
つまり「アメリカのSES⇒アメリカのSNS⇒東京のLambda⇒東京のEC2⇒東京のRDS」となりました。
せっかく読んでいただいた方には、何ともつまらん結論ですね。

8.よく考えたらNode.jsではなくJava 8を選ぶべき?


そもそもOracle使うなら、Node.jsではなくJava 8なんでしょうね。
Oracleが作ったものなのだから、標準でOracleにアクセスできないわけがない。
ただそうなるとインライン編集ができなくなるので、Lambdaを使う旨味がどんどん減っていく…感じはしますね。

世間では、Lambdaでどの言語を選択されているのでしょう? デファクトスタンダードは何なのか知りたいです。
Lambdaについては、いろんな選択肢よりも、むしろ「これを選択すれば大丈夫」というソリューションを一つ、提示してほしいですね。

2018年4月22日日曜日

学区ビューア


同等なアプリは、以前ニフティさんで配布していたアプリともう一つあったのですが、どちらも実質サポート終了になってしまったようで、私も困ってました。
無いなら作ってしまえと、作ったのがこれです。

今回作ったアプリはその目的から、当然リリースは日本限定なので、英語を書かなくて良くそこは楽できました。
であれば、通常は英語でやってるアップルとのやり取りも、日本語で押し切れるのではないかと思い、押し切ったところあっさり通りました。
今はgoogleの翻訳もあるから、拙い英語はかえって邪魔かもしれませんね。
今後は主張があるときは、日本語で交渉しようと思います。

技術的には、Podで大量にソースを引き込んでgccでライブラリをビルドしたり、sqliteでBLOBを扱ったり、DBを"Hosting Content with Apple"の仕組みを使ってダウンロードできるようにしたりと、色々新技を身につけました。
それでも2ヶ月くらいでリリースできました。

ブログにも書きましたが、Podのところで正解を見つけるのに大半の時間を使いました。
あと、アプリ内課金の実装で、初めてダウンロードを実装する必要がでたり、初めてアプリ内課金が複数となってしまったので、これを取り扱うための実装を考えるのに、労力がかかりました。

2018年4月14日土曜日

iOS11.3にアップデートされ作業が1日ストップ


iPhoneが、iOS11.3にアップデートの準備ができましたって言うんで、夜間に更新を認めてしまった。
これが問題のきっかけ。
11.2->11.3のマイナーアップデートだから問題ないと思ったんだけど。
よく考えずアップデートしたら、本当に駄目だね。

1. iOS11.3をターゲットに、デバッグできなくなってしまった。
Xcodeを9.2->9.3にしないと駄目だと。
そして9.3にするには、MacOSを10.12->10.13にしないといけない。
大変なことになってしまった。

2. iOS11.2に戻せないか見たら、もう期限切れで駄目だと。
MacOSのアップデートか~色々動かなくなるんだろうな~

3. MacOS10.13のダウンロード開始。6時間もかかったよ。かかり過ぎ。
何とかアップデートし、続いてXcodeもApp Storeから更新。

4. さてようやくビルドし、デバッグモードでRun。
Development cannot be enabled while your device is locked.
出ましたエラー!

5. 一度ケーブルを外し、
「設定」>「一般」>「リセット」>「位置情報とプライバシーをリセット」
改めて繋いでRun。

6. iPhone is busy: Preparing debugger support for iPhone.
まだ出るかエラー!

7. iPhoneを再起動したら、半日ぶりに復旧。
お疲れ様でした。

2018年3月25日日曜日

iOSでSpatiaLiteを使いたいだけなんだけど

spatialiteDBKitというのを導入すればいいだけなんだけど、2週間ぐらいかかったかな。
白紙の状態から始めた場合の手順を、以下に記録します。

1. Apple Developer SiteからcomandlineToolをインストール

以下5.のgeosのくだりまでは、
https://github.com/andreacremaschi/SpatialDBKit
のHow to Useの通り。

2. brewがない人は、以下からインストール
https://brew.sh/index_ja

3. automake等をインストール
brew install automake autoconf libtool

4. podがない人は、
Rubyを最新版にしておく。
sudo gem update --system
podをインストール。
sudo gem install -n /usr/local/bin cocoapods

5. 所望のプロジェクト下で、Podfileを作成
pod initでPodfileを作る。
・# use_frameworks!は、コメントアウトのまま。
 frameworkにすると、#importや#includeを10ヶ所ぐらい書き換えないといけなくなる。
・pod 'SpatialDBKit'の前に、pod 'geos', '~> 3.4.2'としておく。
 geosの3.5.0や3.5.1ではうまくいかないため!

6. pod installを実行。

7. 出来上がった .xcworkspaceファイルをXcodeでオープン。

8. ビルドが通らない。
How To Useの通り、spatialite.cの#includeを変更。

9. SpatialDatabase.mがおかしい。
#import <spatialite.h>を加えれば、ビルドは通るが、EXC_BAD_ACCESSエラーに見舞われる。
Podではなぜか最新版のSpatialDatabase.mが取得されないので、手動で入れ替え。

10. ようやく動くようになる。