mitolab's diary

東南アジアで頑張って生きてる人のブログ

最近のマレーシアの農業事情

ども、インドに2/1から行くのですが、その次はマレーシアに行く予定です。ということでマレーシアの、特に農業事情やagtechのことを調べてみました。

マレーシアって?

人口は約3000万人、首都はクアラルンプール。名目GDPは5%前後でASEAN諸国では中間くらい。1人当たりの名目GDPは25,638ドル(2014年, 世界銀行)でASEANではシンガポールについで2位の水準。

言語はマレー語、英語。民族は多民族国家で、マレー系、中国系、インド系の順に多い。宗教はイスラム教が60%、次に仏教20%、キリスト教9%、ヒンズー教6%。政体は立憲君主制

その他基本的な事項は以下でどうぞ。

マレーシア基礎データ | 外務省

図解 ASEANを読み解く

新品価格
¥1,944から
(2016/1/25 23:01時点)

マレーシアの農業事情

マレーシアは元々資源が豊富で、天然ガスや原油の輸出が盛んです。農業の分野でもパーム油の輸出量は現在も世界屈指だそうです。 国内総生産における農業の割合は、約9%(*1)とASEAN諸国では低めですし、農村人口もASEAN諸国の中では唯一減少に転じていますが、恵まれた資源を背景に工業化してきたおかげで、アジアの中でも有数の投資環境となり、農業の分野においても他国と協力し高度化を図っているようです。

参考:

agrinasia.com

農林金融2014年12月号 より、以下画像参照。

f:id:mitolab:20160126165153p:plain

f:id:mitolab:20160126170034p:plain

土地生産性: 農業生産額÷農業用地面積

労働生産性: 農業生産額÷農業従事者数

これらの状況を見ると、農業の生産額はそれほどないかもしれませんが、高度化という面では他のASEAN諸国よりもかなり進んでいると思われます。

一方で、国内食料自給率を品目別に見てみると、鳥肉や魚介類の受給率は100%なのに対して、コメは70%、野菜は66%、果物は40%程度と、自給率はまだまだ良くはないです。しかもマレーシアの人口の60%を占めるイスラム教徒はハラール食を食べると思われるので、その辺も考慮すると、より自給率を上げていく必要がありそうですね。

参考:

nna.jp

malaysia-ryugaku.hateblo.jp

http://www.maff.go.jp/j/kokusai/kokusei/kaigai_nogyo/k_syokuryo/h23/pdf/asia03.pdf

AEC(ASEAN経済共同体)(*2)による農業への影響

2013年時点の記事内にて、テンク・アリフ氏(マレーシア農業研究開発研究所経済技術管理研究センター長)によると、

ASEAN域内の農産物貿易では,マレーシアは既に92%の品目で,関税を撤廃していて,現在でも保護されているのは,コメ,アルコール類,タバコなどの限られた品目です。

また、

ASEAN域内の関税はすでに撤廃されていることや,非関税障壁と行政手続きによる事実上の保護政策が存在していることを考慮すると,AECがマレーシア農業に与える影響は,あまりないと考えられます。農業部門に限らないAECの全体的な影響としては,自由化による全般的な経済厚生の増加と海外からの直接投資の増加が期待されます。

とのことで、マレーシアでは国内の農産業に与える影響は少なく、むしろ海外からの投資が集まり農業分野においても高度化の好機になると思われます。

先進的な取り組みを行っている農家・企業

techなところはなかなか探せず...とりあえず調べた分だけリストしてみます。

ハッピーフレッシュ... お野菜の速達サービス

シリーズAに参加したファンドに、500startupがいたり、日本のファンドBEENEXTがいたり、注目度は高いようです。→ agFundernews

TITI ECO FARM... いわゆるエコツーリズム。宿と、農業体験、有機野菜やオーガニック商品の販売をしているようです。サイトがとても綺麗です。

ZENXIN... オーガニックフードを中心に6次産業的に事業を展開している企業。各国のオーガニック認証も受けているようです。サイトが充実していてありがたいです。

以上です。

*1) マレーシア基礎データ | 外務省 より

*2) AECというのは、ASEANが掲げる3つの共同体(安全保障共同体、経済共同体、社会・文化共同体)のうちの1つです。2015年の12月31日をもって発足しました。AECでは、ASEAN域内での物品の自由な移動、サービス貿易の自由化、投資の自由化、資本の自由な移動、熟練労働者の自由な移動等がうたわれています。2009年に各共同体のロードマップが制定され、そのうち経済共同体に関しては以下のように記述されています。via 経済産業省: 東アジア統合に向けて

とある2年目フリーランスエンジニアが30歳過ぎて旅にでた理由

新卒で入社した前職を辞め、フリーランスエンジニアになってはやくも1年と4ヶ月がたちました。2016年で32歳になる予定です。世間的には最も働き盛りな時期、エンジニア的には35歳定年まであと3年ほどの時期に私は何をしているかといえば、旅にでています。今3カ国目で次はインドに行く予定です。

「うわぁ、30歳過ぎたおっさんが自分探ししてるよ...」私より若い人から見ればそんな感じじゃないでしょうか。親族にはこの歳までふらふらして心配かけて申し訳ない...とは思いますが、それ以外の人にどう思われようがいいんです。説明するのが面倒なので、自分探ししてますって言うのにはもう抵抗が無くなりました。

までも説明は面倒じゃないですね(え)、理由は単純に今後の人生を何のために使うかをリアルな世界を見た後に決めたいと思ったからというのが正直なところです。記事のタイトルへの回答はこれで完了ですね...。以降は全て余談になっちゃいます。

今後、恐らくゆるやかにジョブチェンジしていくと思うんですが、その過渡期にある、いちエンジニアのポートレートとして現状とか気持ちとか振り返りとかを記しておこうと思います。

とりあえず今の状況は?

フリーランスエンジニアとして生計を立てています。2015年の10月から海外を巡りつつお仕事をしたり、自身のアプリを開発したり、現地の面白い人に会ったりしています。せっかくなので観光地に行ってみたりもしています。その状況は随時別のブログで発信しています。この記事を書いている2016年1月時点では、タイ、ミャンマーに続きベトナムに滞在中です。

DotsNest|フリーランサーの世界ノマド日記

ジョブチェンジ先の予定

今は興味があり、社会的にも意義があり、自身のこれまでのスキルも活かせそうで、且つ成長が期待できる分野として、AgTechに注目しています

AgTechというのは、Agriculture + Technology の略で、主に農業分野の課題に取り組むスタートアップ(新興企業)や分野そのものを指します。ただ一言にAgTechといっても、ドローンを使った最適な農地管理を扱うものから、新しいバイオ燃料の生成するもの、ECサイトで新鮮な食品を提供するなものなど割りと幅広いです。

なぜ興味があるのかというと、大学時代に異様なまでに植物に興味を持ち、植物の声を聞こうと思ってオペアンプを組み合わせてアナログ回路を組んでみたり、休学して沖縄本島から約300Km南にある宮古島でサトウキビを刈りつつ自給自足のような生活をしたり、好きな植物をやたらスケッチしたりしていた経験が大きいです。今思えば単純に多感な時期だったとも言えますが、その時の時間も忘れて没頭していた感覚や自然に救われたという感覚が忘れられず、10年たった今も引きずっていて、植物や自然に関わる仕事がしたいと思っています。

社会的にいえば、

人口は各年7760万人ずつ増加しており、2050年には100億に達すると予想される。それと同時に、ミドルクラスは2030年までに倍増すると予想されている。収入が増えると食費支出が増え(エンゲルの法則)、動物性蛋白質をより多く食べる(1ポンドの牛肉に8ポンドの穀物を要する)。経済的に豊かな人びとが増え、食糧と燃料と繊維(衣料)の需要が増えると、専門家の予測では今後35年以内に農業生産、とくに穀物の生産量を今の倍にする必要がある。

via TechCrunch: グリーンテクノロジの新しい女王はアグテック(AgTech)だ

という状況があります。なので投資もこのところAgTechに対して集まってきており、今ではFinTech(金融関連テクノロジ)に対する投資額をしのぐ程に急成長している市場になっています。元々参入障壁の高い市場なので、むしろ今からだと遅いくらいかもしれませんが...。

ジョブチェンジ先を決める上でのポリシー

今後取り組む事を絞る上で1つポリシーのように考えていることとして、開発途上国で先進国が踏んだ轍を踏まないような開発を」というものがあります。そう考えるようになった1つのきっかけは、ちきりんさんのこちらの記事でした。

blogos.com

この記事から

開発途上国は先進国を真似るのではなく、時代や国に合わせた別の道を模索してよりよい発展を遂げるべきだ」

という主張を汲みとったのですが、その主張に私はすごく共感しました。この記事では鉄道の話でしたが、仮にエネルギー(環境)問題でいうと、先進国は既に火力原子力を使って多くの失敗をしてきました。前者はCO2を短期間で急激に増加させ、地球を人や他の動植物が住みにくい環境へと少しずつ変容させていますし(その問題に悲観的/楽観的視点で取り組んでいるのがイーロン・マスクだと思っています)、後者も放射性物質放出による人体への影響や技術の悪用など様々なマイナスの副作用があります。そういった問題を何度も何度も開発途上国で発生させ、後から対策を講じるのは非合理的ですし、地球がいくらあっても足りません。なので、先だってそういった環境問題に取り組んでいる先進国の技術を発展途上国で活かしつつ、別の発展を遂げることは世界的にみて意義があると思われます。

余談ですが、以下のサイトはagtechや開発途上国について幅広く取り扱ってくれていて、重宝しています。

AGRI IN ASIA | アジアの農業の今を伝えるメディア

トジョウエンジン | 途上国のイメージを豊かにするノンストップ・デイリーマガジン

AgFunderNews - At the intersection of agriculture, technology and investment

今の自分が持っている武器は?

過去にIT業界でやってきたといっても、アプリ作ったり簡単なサイト作るとか、簡単な電子工作とかそんな程度で、正直AgTechのコアとなりうる知識やスキルは持っていないと思っています。そもそも大学も文系出身ですし、単に好きでコンピュータを学んできた身です。ただプログラマとしての基本的な思考回路とかプロダクトを作る上での基本的な経験は持ち合わせているつもりですし、フットワークの軽さは20代並だと勝手に思っていますのでその辺はもしかすると武器になるかもしれない...それくらいです。

現状自分には何が必要か?

上記目標を実現するために必要なのは、技術よりもまずは知見を広げることだと思いました。本当にこの分野が自分の持っている技術や興味にfitするのかを見極めたいし、AgTechの世界全体の市場の動きとか、どのくらいの企業がどんなことをしているのかとか知らないことだらけなので、まずはもっと知ろうと。

ではどうやって知見を広げるか?

  • ググる(ネットで検索)
  • よさ気な企業の担当者または個人に会って直接お話しを伺う
  • もしよさ気な企業とマッチすれば就職してみる

上から順に実行してみました(最後以外)。日本じゃなくて海外で。

なんで海外?といえば、今まで何度か海外に出ていて、その時に得られた経験がコスパ高かったからというのと、上記のちきりんさん経由のポリシーも持っていたからでしょうか。それにフリーランスになってからはグローバル化みたいなのを感じることが多かった*1ので、"とりあえず海外"という気持ちが強かったです。

で、基本的には東南アジア〜インド〜アフリカ〜ヨーローッパ〜北米〜南米とかで移動して世界一周して考えようと思っていたわけですが、上記のagtechについて調べてったり人に会ううちに、「もっと学びたい、はやく動きたい...」という気持ちが大きくなってきているので、世界一周なんてしないかもしれません。

知見は効率よく広げられたか?

旅に出るまで

海外にでるまでの目標はとりあえずお金を効率よく貯めること。だったので、とりあえずそれまで拠点にしていた沖縄よりも単価の高い東京に場所を移し、受託開発のお仕事をひたすらしました。幸い前職でほぼiOS開発専門だった、且つ世の中としてはスマートフォン移行の全盛期だったおかげで、アプリ開発者な私としては仕事にあぶれることなく1年と4ヶ月も生きのびつつ、海外に出るための資金も貯めることができました。

旅に出てから

海外に出た当初の方針としては、

  • 自身のアプリを作って固定収入を得る
  • 仕事も続ける
  • 知見を広げる

この3つを同時進行で実行することでした。キャッシュフローを安定させるため、自身のアプリを作る事と仕事を続ける事は決めていました。でも、振り返ってみると、最初の2ヶ月は実質仕事が9割で、自身のアプリが1割、知見を広げる部分は最も重要なはずなのに全くできていませんでした。これは単純に自己管理能力の無さゆえです。

ただ、海外にでたこと自体は正解だなと思えました。リアルな課題や新鮮な情報を具体的に聞けるので、自身がどう関われるかイメージがしやすくなりますし、その熱量を分けてもらうこともできます。あとなにげにいいのは物価が安いこと(ただし東南アジア諸国の場合)。同じ資金でも日本にいるより約2倍長く生き延びられるので。

今後の方針は?

知見を広げることを第一にしたいと思います。ただ、調べるうちにもっと詳しく知りたい、動きたいと思う気持ちが強くなっているので、今後はより分野を絞って、深く学ぶことにシフトしていこうかなと思います。そのスパンが早ければ早いほどいいですが、半年〜1年くらいをめどにしたいと思います。

それと、旅に出て気づいたのですが、数珠つなぎで旅するのは非常に疲れます。まず荷物が重い、その上各国に渡るためのチケット、VISAの手続きも面倒、移動時間ももったいないし疲れる、各種スケジュール調整しずらい、etc...。

なので、私みたいな人にとって、海外に出て何かを探す場合は、拠点になる都市を決めてそこを中心に廻ったほうが得策だと思います。例えばバンコクとかいいです。バンコクだと、

  • 生活コストが日本の1/2(実感値)
  • 東南アジア、南アジアを巡る際にLCCが多数ある(AirAsiaとか)
  • アパートを借りるのに日本みたいな敷/礼金ないし格安だし結構広くて快適

というメリットがあるので、拠点にするには最適です。ということで、実際今はバンコクを拠点にしています。アフリカ大陸だと、、どうなんでしょうね、調べる必要があります。そのまえに資金が尽きる可能性もありますので、固定的にキャッシュを得られる仕組みを持っていると選択肢は広がると思います。

さいごに

半分あきらめて生きる (内田樹の研究室)

こういう文章とか、

古市憲寿さんの著書

とかディストピアなコンテンツはとても好きなんですが、個人的には、これを鵜呑みにしないで反面教師として捉えた方がいいと思うんですよね。というかディストピアにさせないためのコンテンツだと思うので、中立でとか遠目で待つとかじゃなくて動いていくことを大事にしたいので、今後も自分なりに頑張っていこうと思います。

*1) フリーランスになりたての頃、試しにクラウドワークスで仕事をしようと思ったことがあり、見積り資料を作って2通出してみたのですが、どちらも受注には至りませんでした。その時インドやベトナムの企業も見積りを出していました。彼ら(彼女ら)は日本の相場より何倍も安いので、きっと彼ら(彼女ら)が受注したんだと勝手に想像しました。この時「自分は日本だけじゃなくて海外の企業とも対峙していかないといけないんだ」と、個人と世界がものすごく近い位置にあると実感して、日本だけにいてはいけないなという思いが強くなりました。

インドのバンガロールへ行ってきます

今後ジョブチェンジをするにあたって何をするか決める旅もあと2ヶ月と迫ってきました。 前半はだいぶお仕事をしてしまい、海外にいる意味があまり無かったな...と少し後悔していますが、概ね絞れてきたのでまぁいっかということで、残り2ヶ月動いていきます。

ということで、2/1から1週間くらいインドのバンガロールに行ってきます。

なんでバンガロール

まずインド自体が世界的に見てもトップクラスの経済成長率を誇り、世界中から投資を受ける魅力的な市場です。常に数十年先を見据える起業家であるソフトバンクの孫さんもインドに対して1兆円レベルで投資する予定とのことです。

そんなインドの中でもバンガロールは「アジアのシリコンバレー」と言われるほどIT産業の中心地となっていて、インテルやグーグルなどの有名な企業の研究所や起業家が多く集まっていると聞きます。前職含めコンピュータ関連のお仕事に携わってきた私にとっては魅力的な土地です。

それに、最近はオーガニック(農薬を使わない)農業に興味を持ってアジア各国の事情を調べているんですが、

有機農産物国際競争力センター(ICCOA)によれば、インドのオーガニック市場は、バンガロール、ムンバイ、デリー、チェンナイなど都市部を中心に拡大している。2013 年時点での市場規模は 250 億ルピー(輸出額含む)を超え、年率 20%の勢いで成長している。このうち、バンガロールが占めるシェアは約 5%とインド最大である。

via: バンガロール、急ピッチで広がるオーガニック文化 | インド進出支援のTeam INA

という記事や、

投資額は3百万ドルから1千万ドル程度までの範囲で、資金調達時の企業の売上高は5百万ドルから1千万ドルの企業にわたる。このように、オーガニックフードを扱うスタートアップやアーリーステージのベンチャー企業に対するベンチャーキャピタルの投資が盛んである。

via インド農業の次なる大きな投資先、オーガニックフード | AGRI IN ASIA

という記事、さらに

特に、バンガロールはオンライングローサリーのキーマーケットとして、牽引していくと予測されていてムンバイとデリーは追随すると言われています。

via インドのオーガニック市場がアツイ : Startup story of PEBBLE BRANDING

という記事を見るにつけ、これは行ってみる価値は十二分にあると判断し行ってみようかなと思いました。

バンガロールってどんなところ?

グーグル先生

f:id:mitolab:20160124004957p:plain

場所

via googlemap

地理&気候

バンガロールは南インドの南西、カルナータカ州に位置し、デカン高原の一部をなすマイソール高原の中心部に位置する。海抜の平均は920m、北緯12度58分、東経77度34分に位置する。安定した地殻の上にあるため、地震はほとんどない。

かなり標高が高いので涼しそうですが実際はどうなんでしょう。地震が無いのは日本に比べて、また自然を相手にする産業にとってはプラスポイントですね。

バンガロールは、雨季と乾季がはっきりしているサバナ気候(ケッペンの気候区分 Aw)である。バンガロールは高い標高にあるため、時折、夏に不快な熱波が発生するが、通常、一年を通してより穏やかな気候を満喫することができる[5]。 最も寒い月は平均最低気温が15.4 °Cの12月で、最も暑い月は平均最高気温が32.8 °Cの4月である[6]。 これまでにバンガロールが記録した最高気温は38.9 °C(1931年3月)で、最低気温は7.8 °C(1884年1月)である[7][8]。 冬の気温はほとんど12 °C以下に下がらない。夏の気温はほとんど34–35 °C以上は超えない。バンガロールでは北東と南西モンスーンの両方の影響で降水を観測する。そのため最も降水量の多い月は9月と、10月、8月である[6]。夏の暑さは、かなり頻繁に降る雷雨によって緩和される。雷雨は時折停電や局地的な洪水を引き起こすこともある。24時間降水量の最高は1997年10月1日に記録した179 mmである[9]。

とりあえず、2月はまだそこまで暑くなく、雨も降らないようなので過ごしやすそうです。

via wikipedia

インドのオーガニック作物認定制度

インドはオーガニック作物に関して国家レベルの認定制度を持っているようです。というのも、企業が諸外国に輸出する際、オーガニックとして売り出すにはUSDA(米国農務省)、EU、Control Union(認証検査機関)、OU Kosher(ユダヤ系の検査機関)といった機関の認可を受ける必要があります。それらの機関をパスするため、インド側で一定の基準を設定しているようです。

via インド農業の次なる大きな投資先、オーガニックフード | AGRI IN ASIA

インドのオーガニック作物の統計データ

source: National Centre of Organic Farming Department of Agriculture and Cooperation Ministry of Agriculture Government of India 2010-11 & 2011-12

認定をうけた州別農地面積

  1. マディヤ・プラデーシュ州: 約290万ヘクタール
  2. ヒマーチャル・プラデーシュ州: 約63万ヘクタール
  3. ラージャスターン州: 約22万ヘクタール

バンガロールが属するカルナータカ州は約9万ヘクタールで、マディヤ・プラデーシュ州の約1/32倍。全然少ないですね。2,3位はインド上部国境沿いに近いところにあります、どちらもヒマラヤに近く標高の高い土地です。今は消費地からはやや離れた場所から農作物がきているかもしれませんが、カルナータカ州政府の農地拡大政策もあるようなので、今後は近郊の農地が増えそうですね。

※ 2010-11年のデータ。国による認定を受けて現在耕作されている土地、耕作途中の土地、認定を受けている途中のもの、てつかずの土地を含めた面積。

認定作物生産高ランキング(その他を除く)

  1. 薬草やハーブ類: 約180万トン
  2. 綿花: 55万トン
  3. Old Seeds(植物性油?): 約36万トン

※ 2010-11年のデータ

1位は綿花だと思ったら、薬草やハーブでした。綿花は食べ物ではないので輸出用として認可を受ける必要はないということでしょうか。

オーガニック農業体験できるところ

今いいなと思っているところは、GreenPathというバンガロール近郊にあるファーム。日本で言う6次産業みたいな展開をしていて、直営店をバンガロール中心街に持ちつつホテルも経営しており、そこでとれたての野菜を使った料理を食べられるようです。またオンラインストアも持っていたり、国のオーガニック認可もとっているかなり先進的な農家のようです。

The Green Path | Home

その他のオーガニック農業体験ができる場所はWWoof Indiaから探せます。 ただし、WWoofは国別に分かれていて、それぞれの国で一定金額を支払わなければいけません。GreenPathに限っていえば、WWoof経由か直接メッセージを出してくれればボランティアできると書いてあったので、後者でトライしているところです。

それから、以下のサイトではインド各地で農業(ボランティア)体験ができる場所を紹介しています。

lbb.in

40 places to Volunteer Travel in India
www.thealternative.in

農業やオーガニック食品、食に関するスタートアップ

とりあえず調べた分だけ幾つかリストアップします。

EC系

Organic Vegetables, Fruits, Dairy, Poultry and more Delivered to Your Home

http://www.isayorganic.com/demo/index.php/

Buy Natural, Organic and Herbal Products Online at Joy by Nature in India – Joybynature.com

http://ekgaon.com/ekg/index.php

Online organic store of certified branded organic products | Organic Shop

上記すべてオーガニック食品を販売するECストア。どれも同じに見える...。乱立状態。ちなみにリアル店舗を持つ所もあります。

参考: Exclusive: Organic farming venture Lumiere raises Series A funding

インド農業の次なる大きな投資先、オーガニックフード

その他

InBento 日本人が立ち上げたオーガニック素材を使った日本食ブランド。日本食 x オーガニックということで受けがよさそうですね。

Zomato - Never have a bad meal. こちらは、かの有名なVCセコイヤキャピタルが出資しているそう。日本で言う食べログとかRettyの位置にあるレストランのレーティングサービスです。 既に複数の国で展開しているそう。

Bira91 | The Original Indian Craft Beer こちらもセコイヤキャピタルが出資するビールのスタートアップ。サイトいくとわかるんですが、めっちゃ洒落ています。既にインド国内の主要都市で展開しているそうです。

参考: http://pebble.blog.jp/

インドでオーガニック農業を始める社会的意義

貧困層を減らせる可能性がある

開発途上国においては、常に貧富の差が大きく、貧しい人々は農家をして自給したり、業者に売り(安く買い叩かれながら)生計を立てている場合が多いです。例えばそういう農家とパートナーシップを結んで技術や販売ルートなどを提供し、作物を引き取って海外に輸出といったビジネスモデルであれば、貧困層の人間を減らすことができるかもしれません。綿花農家なんかはひどくて、

同国第2の州であるマハラシュトラ州では1日平均約12人の農民が自殺し、その数は増加している。世界の供給が過剰となったため綿花価格は下落し、インドでは地方の貧困が深刻化している。

via bloomberg.co.jp: 農民の自殺、インドで増加-綿花価格下落で地方の貧困深刻化

とのこと。こういった不幸をできるだけ減らせるといいですよね。

増加しつづける人口に対しての食糧需給

インドは言わずもがな世界第一の人口増加率を誇ります。2022年までには14億人に達し中国を抜き、さらに2030年には15億人に達すると国連が予想しているそうです。 via CNN: インド人口、22年までに中国に並ぶ その後最多に 国連予測

また世界的に見ても、今後数十年で起こる人口増加や温暖化などによる食料危機の可能性も大いにあります。

まとめ

ということで、インドでオーガニック農業のビジネスを始めるという選択は、社会的にも意義があり、市場としても大きく発展していきそうなので、良いのではないでしょうか。あとは実際にいってみて、どうなんだろうっていうのを見れるといいなと思います。

訪問予定の場所など

実際にいけるかどうかわからないですが...とりあえず。

InBentoさん

日本人経営者ということで、同じ日本人としてインドでのビジネスのリアルな部分をお伺いできそうだなと思っております。

The Green Path | Home

こちらは、農業体験できるところ で挙げた多角化経営をしている農家さん。実際に1週間くらい滞在してノウハウを見てみようと思っています。

あとは、時間的に余裕があれば、

Organic Vegetables, Fruits, Dairy, Poultry and more Delivered to Your Home

こちらのショップのオフライン店舗を訪れてみたいです。

socket.io(SIOSocket)をネタにJavascriptCoreに入門してみる with Swift

Motivation

かつてSIOSocketなるSocket.IOiosクライアントがありました。

"かつて"というのも、このクライアントはObjective-Cで書かれているのですが、2015年の3月にSwift製公式クライアントが発表されたことにより、お役御免で開発STOPとなってしまいました。

ただ、僕はこのライブラリ面白いなーと思ったところがあって、それはminifyしたjsのコードと少しのソースで、Objective-C製ライブラリの如く使えるようにしていたところです。

例えば、

io.on('join', function (args) {});

みたいなのは、

[self.socket on: @"join" callback: ^(SIOParameterArray *args){}];

こんなふうに書けていました。

こういうのを、少しの労力で作れるなら、javascript界(以後jsと書きます)の膨大な資産をios界でも気軽に使いまわせるのでは?と思い興味を持っていました。

ということで、今回はこのSIOSocketをSwiftで換装してみて、時が来たら同様のことができるように前知識を蓄えておこう、というコンテンツになります。

JavaScriptCoreについて

今回のようにjsのコードをベースにしたswiftクライアントを作る上で欠かせないのがJavaScriptCore.framework。 これは端的に言うと、JavascriptObjective-C(Swift)をブリッジしてくれるObjective-C APIです。2013年からあって、Mac/iOS両方で使えます。

※ 元々Objective-CAPIなので、Swiftでは使いにくい部分がままあります。追ってその点についても触れていければと思います。

JavascriptCoreを使うには

frameworkとして提供されているので、Linked Frameworks and Libraries のところからいつもの様に追加して、使いたいところで import JavaScriptCore してあげれば使えるようになります。

JavascriptCoreImport.png

Swift上でjsのコードを実行する

基本的な例を挙げてみます。

// 1. コンテキストを作成
let context:JSContext = JSContext()

// 2. javascript(ここではfactorial function)をコンテキストに渡して評価する
context.evaluateScript("var factorial = function(n) { if(n<0){return;}if(n===0){return 1;}return n*factorial(n-1); }")

// 3. コンテキストには既にfactorialメソッドが登録されているので、それを呼ぶ
let result: JSValue = context.evaluateScript("factorial(3)")

// 4. 返ってきた値をよしなに変換して使う
print(result.toInt32())

また、3の手順は、以下のように呼ぶこともできます。

let factorial:JSValue = context.objectForKeyedSubscript("factorial")
let result:JSValue = factorial.callWithArguments([3])

以下、各用語や概念の補足です。

JSContext

1つのJSContextインスタンス(コンテキストと呼ぶ)を生成したとき:

  • コンテキストはグローバル変数で、jsでいうwindowオブジェクトに相当する
  • コンテキストを通して、jsに変数を登録したり、jsの実行結果を取得したりできる
  • コンテキストを通して取得/生成したJSValue(後述)は、コンテキストに強参照を持つ

JSVirtualMachine

1つのJSVirtualMachineインスタンス(vmと呼ぶ)を生成したとき:

  • vm上に複数のコンテキストを持つことができる
  • vm上に存在する複数のコンテキスト間で変数を共有できるが、vmをまたがる共有はできない(それぞれのJSVirtualMachineはそれぞれのガベージコレクターとヒープをもって管理しているため)
  • 1つのvmにつき同時に実行できるスレッドは1つ(= jsを複数同時に実行したいなら複数vmを立ち上げる必要がある)

JSValue

1つのJSValueインスタンスを取得/生成したとき:

JSVirtualMachine, JSContext, JSValueの関係図

vmImage.png

WWDC2013のセッションスライドに少し加筆しました

func evaluateScript(script: String!) -> JSValue!

評価の結果返り値があれば、ここで取得することもできます。ここでは返り値は特に指定していないので、undefinedになります。

func objectForKeyedSubscript(key: AnyObject!) -> JSValue!

コンテキスト上にある変数にアクセスすることができます。上記の場合はfactorial変数を取り出しています。これは、Objective-Cであれば、

context["factorial"] というふうにsubscriptをつけることで取り出せたのですが、swiftだと上記のようにメソッドを呼ばなければいけない上に、ドット記法(例えばwindow.onload)で取り出すのもできないようです。

callWithArguments(arguments: [AnyObject]!) -> JSValue!

先に取り出したfactorial関数に引数を渡すことができます。面白いのは、引数が配列になっていて、且つAnyObject!になっていること。つまり、JavascriptCoreさんが、

  • 配列のindex順にjsのfunctionに渡してくれる
  • swift側の型とjs側の型を自動的に変換してくれる

ということになります。

js上でswiftのコードを実行する

大きく分けて2種類の方法があります。

1. クロージャを使う

まず基本ルールとして、

  1. JSValueのキャプチャは避ける -> 代わりに引数として渡す
  2. JSContextのキャプチャは避ける -> 代わりにJSContext.currentContext()を使う

と、WWDC2013セッションのビデオでは言っていましたが、普通にキャプチャすると強参照になってリークしやすくなるので、weakを使いましょうということと認識しました(後述しますがunownedはJavaScriptCoreObjective-CAPIということで使えない模様)。

※ ちなみに、objcのブロックとswiftのキャプチャの違いは、

をご参照ください。

では、クロージャを使った例を示します。

let context = JSContext()
let say: @convention(block) String -> String = { str in
    return "say \(str)!"
}
context.setObject(unsafeBitCast(say, AnyObject!.self), forKeyedSubscript: "say")
print(context.evaluateScript("say('hello')"))

// もちろんこのようにも実行できる
let sayFunc = context.objectForKeyedSubscript("say")
print(sayFunc.callWithArguments(["hello2"]))

上記は、jsのコードにswifitで書いたfunctionを渡し、jsのコードとして実行するサンプルです。 あまり見かけない単語が幾つか出てきています。

@convention(block)

AppleのドキュメントのClosuresの部分をみると、Objective-CのブロックとSwiftクロージャは互換性があるので、@convention(block)アトリビュートをつければ使えるよとのこと。

元々、JavaScriptCore.frameworkがObjective-C APIなので、このような処理をする必要が出ています。

unsafeBitCast

上記@convention(block)アトリビュートによって、sayオブジェクトはObjective-Cのブロックとしてコンパイル時には扱われますが、そのままだと、context.setObject~のところで、エラーが出てしまいます。objectをAnyObject!として渡さなければならないからです。なのでここはエラーをさけるため、unsafeBitCastを使っています。

<<余談>>

元々Objective-CAPIなので、Objective-Cで書くととても楽です。特にblockのところはObjective-Cだと、このように書けます。

JSContext *context = [[JSContext alloc] init];
context[@"say"] = ^(NSString *str) {
    return [NSString stringWithFormat:@"say %@!", str];
}
NSLog(@"%@", [context evaluateScript:@"say('hello')"]);

Swiftより断然直感的ですね...。

2. JSExportを使う

ここは今回使っていないので、説明は以下の参考リンクをご参照ください。

JacaScriptCoreの参考リンク

Integrating JavaScript into Native Apps - Apple WWDC 2013 Java​Script​Core Written by Nate Cook — January 19th, 2015 JavaScriptCore Changes for Swift JavaScriptCore.framework の普通な使い方 #cocoa_kansai

SIOSocketをSwift製にする上で気づいた点など

SIOSocket.swiftのソース

https://github.com/mitolog/SIOSocket-swift

todo:

  • テスト書いて、実際にすべてのargumentがおくれるか確認(文字列パラメータしかチェックしてないッス...)
  • JSExportを使ってみる
  • UI適当すぎ

socket.ioを使うには、UIWebView()を使う必要がある

socket.ioのクライアントAPIのページに書いてあるように、socket.ioをスタンドアローンで使う場合、ioオブジェクトはwindowのプロパティとして配置されます。

なので前提として、

  • UIWebView()のJSContextを使う
  • UIWebView()にhtmlをロードする
  • ロードが完了(window.onload)してから、ioオブジェクトを取り出す

必要があります。

SIOSocketでは、以下のように実現しています。

1. UIWebViewを生成し、JSContextを引き出す (SIOSocket.swift_84行目)

socket.javascriptWebView = UIWebView()
            if let ctx = socket.javascriptWebView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") {
                socket.javascriptContext = ctx as! JSContext
            } else {
                response(nil)
                return nil
            }

via stack overflow - Why use JavaScriptCore in iOS7 if it can't access a UIWebView's runtime?

2. window.onloadコールバックをjsに登録する(SIOSocket.swift_97行目~206行目)

let onLoad: @convention(block) () -> Void = {
    /* some code here */
}
socket.javascriptContext.setObject(unsafeBitCast(onLoad, AnyObject!.self), forKeyedSubscript: "swift_onloadCallback")
            socket.javascriptContext.evaluateScript("window.onload = swift_onloadCallback;")
            socket.javascriptWebView.loadHTMLString("<html/>", baseURL: nil)

jsに渡すクロージャで[unowned self] というキャプチャは使えない(SIOSocket.swift_97行目)

最初、

let onLoad: @convention(block) () -> Void = { [unowned socket] in

としていたのですが、unownedがエラーになってしまい、weakに変えたらコンパイル通りました。恐らくswiftにはあって、Objective-Cにはないからだと思います。多分。

callWithArguments()スゲェ(SIOSocket.swift_108行目)

let io = context.objectForKeyedSubscript("io")
let swiftSocket = io.callWithArguments([
    hostUrl, [
      "reconnection": reconnectAutomatically,
      "reconnectionAttempts": attemptLimit == -1 ? "Infinity" : attemptLimit.description,
      "reconnectionDelay": Int(withDelay) * SIOSocketConsts.MSEC_PER_SEC,
      "reconnectionDelayMax": Int(maximumDelay) * SIOSocketConsts.MSEC_PER_SEC,
      "timeout": Int(timeout) * SIOSocketConsts.MSEC_PER_SEC,
      "transports": withTransports
      ]
    ])

これだけのパラメータを軽々と自動的に変換してくれるので、感動でした。SIOSocketはこの部分元々以下のように書いていたのですが、上のようにするほうが楽だしスマートな気がします。

/*!
 *  socket.io client constructor format.
 */
static NSString *socket_io_js_constructor(NSString *hostURL, BOOL reconnection, NSInteger attemptLimit, NSTimeInterval reconnectionDelay, NSTimeInterval reconnectionDelayMax, NSTimeInterval timeout, NSArray *transports) {
  NSString *constructorFormat = @"io('%@', {  \
      'reconnection': %@,                     \
      'reconnectionAttempts': %@,             \
      'reconnectionDelay': %d,                \
      'reconnectionDelayMax': %d,             \
      'timeout': %d,                          \
      'transports': [ '%@' ]                  \
  });";

  return [NSString stringWithFormat: constructorFormat,
      hostURL,
      reconnection? @"true" : @"false",
      (attemptLimit == -1)? @"Infinity" : @(attemptLimit),
      (int)(reconnectionDelay * MSEC_PER_SEC),
      (int)(reconnectionDelayMax * MSEC_PER_SEC),
      (int)(timeout * MSEC_PER_SEC),
      [transports componentsJoinedByString:@"', '"]
  ];
}

JSContextにアクセスするスレッドはどこでもいい

元々のSIOSocketでは、onloadコールバックでioオブジェクトを取得する際に利用したスレッドを保持しておき、そのスレッド上でのみJSContextにアクセスしていましたが、WWDC2013のビデオを見てみたら、JSContextはスレッドセーフとのこと。実際に、元々performSelectorでスレッドを指定して実行していた箇所を外してみたら、うまく動いたので問題ないと思います。

ただし、JSVirtualMachineの補足のところで書いたように、1つのvmにつき同時に実行できるスレッドは1つ(= jsを複数同時に実行したいなら複数vmを立ち上げる必要がある)らしいので、そこは要注意です。

jsを文字列リテラルとして埋め込む場合は、エスケープに気をつけろ

当初は、staticなglobal変数としてsocket.io.jsを読み込んでいました。その際は、以下のエスケープを施しました。

\ -> \\
" -> \"
' -> \'
tab -> \t
line feed -> \n

エスケープ文字列に関しては、AppleのリファレンスSpecial Characters in String Literalsの部分を参考に。

換装しての感想

JavaScriptCoreに関しては、WWDC2013のセッションビデオを見るのが一番理解が進みましたので、超オススメです。

socket.ioの場合、windowプロパティのonloadをキャッチする必要があったので、UIWebViewからJSContextを引き出せる部分が結構キモだなと思いました。

socket.ioみたく、UIを伴わないjsで且つサイズが小さいものだと、swift製クライアントを作る必要性はあるのかな〜と感じました(Underscore.jsとか?)。

ただぶっちゃけ、objcで書いてbridging-headerで読み込んで使ったほうが楽かもしれない。

あと、他にJavaScriptCoreを使ったライブラリがあったら教えていただきたいです。

References

[Node.js] Socket.ioで双方向通信チャットアプリを構築 〜 JSおくのほそ道 #005 ↑ サンプルを作るうえで一部ソースを使わせていただきました。ありがとうございました。

socket.ioクライアントAPI

デジタルノマドに評判のチェンマイでフリーランスエンジニアが生活してみての感想

tumblrからはてなに引っ越してきました。結構というかかなり快適...。はてなさんよろしくおねがいします。

軽く自己紹介

@mito_log 。 沖縄のIT会社に4年ほど務めた後、主にフリーランスiOSデベロッパとして沖縄・東京で約1年活動後、約300万の貯蓄をもって海外ノマド旅行を開始。約半年間、世界各地を放浪しつつ、お仕事したり、もの作ったり、面白そうな人を訪ねたり、イベントに参加しつつ、今後注力することを見つける予定。 今興味ある分野としては、再利用エネルギーや環境問題。

今はチェンマイにきて約3週間がたち、上記とは別で進行中の自社プロダクトを完成させるため、もう1ヶ月滞在する予定。

チェンマイってどんなとこ?

IT業界では言わずと知れたデジタルノマドが集まる、タイの北方720キロくらいにある、タイ王国第二の都市です。

ノマドリストなる世界各地のデジタルノマドスポットをランキング化しているサイトでは、堂々の1位を獲得。

nomadlist.com

1位になる要因としては、主に、

  • 年中過ごしやすい気候
  • 物価が安い
  • インターネットが安定している
  • ご飯が美味しい
  • 治安がいい
  • アクティビティが多い

とかかなぁと思います。大体 「チェンマイ ノマド」でググるといろいろ出てきます。

あと、日本との時差は-2時間です。

チェンマイでの暮らし

そんなデジタルノマド天国なチェンマイ、私がフリーランサーとして約3週間滞在してみての感想を書きます。

TOC:

  • MAYA最強説
    • コワーキングスペース&カフェ CAMP最強
    • AISのSIMを使えば更に最強
    • 食事のバリエーション多く、コスト低い
    • 映画館が併設されていて、安く映画を見られる
    • その他good points
  • チェンマイの疑問点
  • チェンマイはこんな人におすすめ

MAYA最強説

MAYA(地元の人はメィヤ~と発音する)とは、5F建てのショッピングモールで、イオンモールとか駅直結のデパートのようなものを想像してもらえればいいかもしれません。そこでは、洋服屋さん、フードコート、ゲームセンター、映画館、カフェがあったり、地元美術大学の展示をしていたり、室内外問わずイベントをしていたりします。

※ プチ情報:市街(いわゆるお堀付近)からであれば大体ソンテウという乗り合いタクシーで20~30バーツ/人でいけるはず。複数人で乗ると20バーツで交渉しやすい。

コワーキングスペース&カフェ CAMP最強

で、ノマドワーカーにとって何がいいかというと、そこの5Fに入居しているC.A.M.Pというカフェが素晴らしいのです。詳細は以下の記事が参考になります。

チェンマイのコワーキングスペース「C.A.M.P. 」はノマドワーカーにおすすめの仕事場だった
dotsnest.com

ほぼ上記で漏れはないのですが、プチ情報を挟むと、チェンマイ大学や高校?が近いので、夕方以降は学生さんが流れ込んできます。日中はデジタルノマドな欧米人の方が多めです。

たまたま隣に座ったpeterさんはbitcoin関連の仕事をしていて、「weekdayはいつもここにいるぜ、毎日ボタンを押してるぜ、日本には居合の勉強でいったことがあるぜ」って言っていました。bitcoinよく知らなかったので、調べてみよう...みたいな自身の知識と交友の幅を広げるような出来事もありました。

ほぼ完璧なC.A.M.Pですが、唯一欠点として挙げるとすれば、たまに停電することです。ただ割りとすぐ復旧するので、それまではテザリングで我慢です。

AISのSIMを使えば更に最強

上記記事中にもありましたが、AISという日本で言うプロバイダのような会社と本カフェが提携しているようで、AISの特定のSIMを契約していると、無制限にWifiが使えます。私もその恩恵を受けて日中は大抵ここに入り浸っています。SIMカードは以下記事のものを使っています。

ノマドワーカー必見!チェンマイでsimカードを購入するなら、AISがおすすめ。
dotsnest.com

1つ付け加えると、泊まる宿によって違うと思いますが、安宿の場合はwifiが貧弱なことが多いです。安宿でなくても、例えばアパート/コンドミニアムなんかだと結局集合住宅なので回線が詰まりやすいです。そこで、AISのSIMカードで通信できる量を多めに持っておいて、宿では通信量を減らしつつテザリングっていうのも、ありだと思います。

食事のバリエーション多く、コスト低い

また、MAYAがいいのは、美味しいご飯が安く食べられて、しかもバリエーションが多いことです。

パッタイ(タイ風やきそば)
f:id:mitolab:20151108183407j:plain

ベトナムヌードル
f:id:mitolab:20151108183402j:plain

カオソーイ(グリーンカレー沖縄そばみたいな)
f:id:mitolab:20151108183355j:plain

マンゴーライス(マンゴー+もち米+ココナッツミルク)
f:id:mitolab:20151108183350j:plain

ココイチのカレー
f:id:mitolab:20151108183337j:plain

etc... 色々なものが食べられます。

大体30~60B(約105~210円)で食べられます! ただココイチは例外で、税金含めて約1000円弱しました。日本と変わらない値段でした。

映画館が併設されていて、安く映画を見られる

日本公開より一足先に映画を見ることができます。例えば2015年11月8日で公開しているのは、

007シリーズ最新作のスペクター
f:id:mitolab:20151108184115j:plain

この作品は、日本だと、12月一般公開予定です。

気になる料金は、サービスデーで100B(約350円)からあってシートによって料金が変わります。激安!

ただ唯一の欠点は、日本語字幕がないこと。英語字幕もありますが、タイ語の作品の場合のみです。 なので、上記のような映画だと英語を頑張って聞き取ることになります。。

あと、映画館で面白いのは2つあって、1つは、映画が始まるまでがやたら長いこと。こないだ見たピーターパンだと、30分くらい広告+プミポン国王を敬うタイムでした。長い。。。

で、もう一つは、お察しの通り、プミポン国王を敬うタイムです。

上記のような、国王の人生のタイムラインを追っかけるような動画が数分間流れて、その間皆起立してそれを見ていなければいけません。従わない場合は不敬罪で逮捕されるとか...。

私はこの事を知らないでダラっとポップコーンをつまんでいたところ、急に周りが起立し始めたので非常に焦りました(もちろん私も起立しました)。

いずれにしても、作業の息抜きに映画館にすぐいけるので最高です。

その他good points

その他の良い点としては、

トイレがウォシュレット完備できれい

f:id:mitolab:20151108183434j:plain

このとおりである。もちろん紙は流せないので、付属のゴミ箱に捨てます。

水・金はナイト・マーケットをしている

f:id:mitolab:20151108185929j:plain

これは開店前の準備中ですが、こんな感じ。

タイ人スタイルいい、かわいい方多い

すみません、チキン野郎なので写真ないです。。

美女大国タイの美人女優・アイドル・モデル TOP20ランキング | ASEAN 海外移住 アジア タイのススメ

このあたりでご確認ください。

チェンマイの疑問に思った点

上記までで大体いいところは述べたので、疑問に思う点をいくつか。

排ガスが結構きつい

どこのサイトでも空気が美味しいといいますが、市街地は車やバイクがガンガン通り、しかも開発中の建物も多く、工事用の車両もあったりで土埃もわりとあります。現地の人もマスクしているほどです。私も一つ買いました。現地デザインのものです。

少し話はそれますが、 タイは、近年まで国策として車の購入を補助する制度を設けていたためか、急激に車の量が増え、結構いい値段しそうな車(しかも軽自動車はほとんど見ない)が多く街を走っています。しかもほとんどが日本車です(こちらの調査を見ると2014年で日系企業のシェアは8割以上)。

また、どこかの記事で読んだのくらいなので要確認ですが、国民は2~3年ローンで車を購入したけれども、その影響で他の出費を切り詰めたため、2013年に補助金制度を廃止してからは、個人消費が低下したそう。

こういう状況を鑑みると、貨幣価値の違いで良い生活をさせていただいている自分はなんだか申し訳ないなぁと思えてきます。

仕事に対する取り組み方が違う...?

これは、日本と比べたらどこもそうなのかもしれないですが、例えば料理店で接客業をしているにも関わらず、常にスマフォをいじっていて、お客さんが来ても基本的に自分の用事が済んだら客の相手をするとか、呼ばれたら対応するとかそんな感じです。また、おしゃべりは当たり前で、オープン直後とかは化粧している方もちらほら。就業時間内なんじゃねーのかよ、と突っ込みたいところですが、ここはタイ。日本の常識では捉えてはいけません。

歩道に段差が多い

街では、基本的に歩道は段差だらけです。案外普通に歩いてても上下運動が多いので、歩道を避け気味になります。。 車いすの方や松葉杖の方は凄い大変そうです。

f:id:mitolab:20151108194005j:plain

バイクに乗っているのにヘルメットを全然被っていない

単純に危ないでしょう、と思います。

f:id:mitolab:20151108194550j:plain

やたらストローを使う

基本的にどんな飲み物でもストローを使って飲んでいる印象です。単純に資源の無駄だなぁと思った次第。

こないだ参加してみた Creative Connectというイベントで、「1日に出すゴミをゲーム感覚で減らしていこう」というコンセプトでアプリを発表されていたタイの方がいました。その方もストローは無駄だとおっしゃっていました。

※ racoon-challengeというアプリ名で、詳細はこちら。日本で同様のコンセプトのアプリならピリカ

チェンマイはこんな人におすすめ

ということで、少なくとも、私のようなフリーランスで場所にとらわれず仕事をされたい日本の開発者さんには自信をもっておすすめできると思います。 それから、スタートアップの集中開発合宿とかにいいかなと思います。ご飯は美味しいし、海外の開発者とも触れ合えるし、文中では触れませんでしたが、贅沢なコンドミニアムを1ヶ月単位から借りられます。私の感覚だと、メンバー3,4名で1万バーツ(約3.5万円)くらいのところを借りるとちょうどいい気がします。