きもちよく文章をかけるiOSアプリ skyline をつくってApp Storeに申請してみました
↑のような感じで、フォントやフォントサイズを自由に変更しながらテキスト編集ができるアプリを作ってみました。
ファイル構成
- ViewController - テキストビューがあるとこ
- SecondTableViewController - テキスト表示の変更ができるとこ
- TextAttributesManager - テキスト表示に関する設定を保持
- Main (Storyboard) - ↑のビューコン2つをUITabBarで、SecondTableViewControllerの前にUINavigationControllerを挟んでいます
ViewController
テキスト編集が行えるUITextViewが生息しているメインのビューコントローラです。
UITextViewだけだとfixしてしまう(抱える文字数が画面外に出るまで増えないとスクロールできるようにならない)ので、UIScrollViewをかませたんですが、これが非常に厄介で
- ScrollViewのTop, Bottom, Leading, Trailingを親Viewに設定
- ScrollViewの子供にViewをかませてTop, B(略 をScrollViewに合わせたあとEqual Width, Equal HeightをScrollViewの親のViewにつなげる
- ScrollView>View>の子供にTextViewをかませたあと、↑と同じことをする
という手順によってうまくスクロールできるようになりました。
さらにScrollViewのAutoLayoutでLeadingとTrailingを設定しても余白ができてしまったので、追加でAutoLayoutの当該項目を参照して「Relative to margin」のチェックを外すとちゃんとピタッと表示されるようになりました。
キーボードまわり
TextViewをタップしたらキーボードがにゅっとでてきます。このとき文章の後半をいじりたいときにTextViewの下をキーボードが覆ってしまって編集できないという問題が発生します。Google先生に聞いてみるとこれはだいぶ既知のようでStackOverFlowやQiitaでTipsが多く得られましたが一番参考になったのは公式リファレンスでした。コードベースはObjective-C時代のものですが基本的なことがしっかり書いてあります。自分はscrollView.contentOffset.y = keyboardSize.height というふうなコードを書いて解決しました。
キーボードを閉じる方法も幾つかあり、例えばスクロールされたときに閉じるという方法がありますが、編集中に別の場所を見に行きたいことがあります。その度にキーボードが閉じるのが面倒だったので、今回はキーボードの上にUIToolbarを生やし、そこにDoneボタンを置くことで対応しました。せっかくなので文字数カウントもツールバーに追加してみました。
テキスト表示設定まわり
UITabBarをへだててフォントとサイズを変更できるビューを実装しました。
まずフォントを全部表示します。UIKitでは、フォントのファミリー名一覧を UIFont.familyNames で、各フォントファミリー名に対応する太さやイタリックなどの情報を含んだ一意なフォント名を UIFont.fontNames(forFamilyName: ) というプロパティに持っています。これをforEachでブン回して配列にappendしました。
サイズはとりあえず ["16", "24", ...] のような感じでStringの配列で持たせてみましたが、実際にUIFontの引数として使うときにCGFloatへキャストしなければいけないので、最初からCGFloatで持っておいたほうがいいかなーという反省があります。
配列ができたら、 tableView(_ tableView: cellForRowAt indexPath: ) のなかで cell.textLabel?.font = UIFont(name: name, size: pointSize) で実際のフォントでレンダリングさせてあげるとフォントが選びやすいです。選択されている値であればチェックマークをつけておきます( cell.accessoryType = .checkmark )。テキストラベルの色も青色にしたかったのですが、UIColorの中にデフォルトのtintColorがなくて戸惑いました。これは、現在いるビューから引っ張ってくることで解決しました( view.tintColor )。
審査
良い感じにできたので、せっかくなのでApp Storeに申請してみることにしました。
この折に、Developer Programに加入します。円高のときは5桁切ってましたが、昨日加入したときは税込みで1万2千円ぐらいでした。
加入できたら、早速Xcodeの Product → Archive をして、Organizer画面でvalidateをしていくのですが 一回ハマりました。bundle identifierもApp IDsに登録してあるので、なんでや~となってたら iTunes Connect に登録していないのがダメだったようです。Xcode側が追加してくれるものかと思っていましたw iTunes Connectにアクセスし、先にスケルトンを作っておきます。この後はすんなり通りました。Upload to App Store... がコケましたが、これは Application Loader で直ipaアップロードさせることで通過できました。
あとはスクショをパシャパシャ撮ったり説明文を埋めたり価格を設定したりしたらSHIP IT! 無事 Waiting for review という状態になりました。
通ったらいいなー
審査に落ちる懸念があるとしたらローカルのフォントを全部ぶっこ抜いてユーザに選択できるようにしていることかなーと思います。ここらへんはフォントの数を減らすしかないのかもしれませんが、とりあえず楽しみに審査の結果を待ってみたいと思います。
楽曲制作のモチベーションを上げるために4thアルバム「ミライトアルマチ詩恩」のティザーサイトを作った話
keisei feat. 初音ミク 4thアルバム 「ミライトアルマチ詩恩」 Special Site
宣言するだとかモチベーションアップにだとか退路を断つだとかそんな中途半端な動機でガッッと新譜のサイトを作ってみました。
基本的な機能としては
- CDのタイトルとアーティスト名がわかって
- トラックリストが見れて
- 試聴ができて
- シェアできて
- いつどこで頒布されるかがわかって
- 最近考えてることを載せる場所があって
- 初音ミクがかわいい(←機能要件)
というものです。
価格とか、頒布部数とか昔はちゃんと書いてたけど今回はいいかな。普通にツイッターで告知するし。
てことで少しずつ作っていて気をつけたこととか詰まったこととかをざっくり振り返ってみたいと思います。
デザイン
深刻な素材不足(MMDの初音ミク1枚しかない)なので、文字が左で初音ミクを右にばんっと添える感じでいきました。とはいえ初音ミクのアイコン性に縋ってたらもし初音ミクもなしで完全オリジナルで何か作ろうとしたら僕は「素材なし」という状態に陥るんだな・・・
シェア動線とか他の動線は下に散りばめる感じで。
デザインカンプ
macOSのSketchを使いました。
全ての画面を洗い出してアートボードに書いていきました。モバイル表示は未実装ですが一応。
ちなみに本番だと初音ミクの色味が若干青がかっていますが、これは後に Camera+ というiPhoneアプリで初音ミクの画像をレタッチした際にいいカラーだなーと思って採用したという経緯があります。
ポーズとか表情についてはここらへん↓
みくみくだんすなう 笑顔もたんに笑顔じゃなくてバックのコンテキストが伝わってくるようなのが好きなので画像検索で漁った結果こういう感じのになった。「笑顔」ってなんなんだろう。 pic.twitter.com/34Nlzw3xg6
— keisei M3-2017春O-20b (@keisei_1092) 2017年2月1日
やりたいことが固まってきて 「そろそろコード書けそうだな」という雰囲気になってきたら、いよいよコーディングに移っていきます。
サーバー
Heroku を使いました。
node.jsのexpressが立っています。
できればWordPressで動いている miraitoarumachi.com の中に独立したページとして立てたかったのですがよさげなソリューションが見つからず、まあいいやという感じになりました。
コーディング
主に jQuery を使っています。
データの保持
次のような感じでバーチャルDOM(でいいのかな)の配列を宣言しておき、スクロールイベントが発生するタイミングで取り替えるというふうにしました。
スクロールを禁止する
スクロールを禁止する、というと若干の誤謬がありますが、
- 下にスクロールしたらあるdiv要素をその連続した次の要素にすげ替えたい
- 上にスクロールしたらあるdiv要素をその連続した前の要素にすげ替えたい
ということを実装するにあたり、「MacのTrackPadによる慣性スクロール」と「スマートフォンのスワイプ」という問題にぶち当たりました。
MacのTrackPadによる慣性スクロール
最近はMacだけの問題ではありませんが、トラックパッドを搭載しているデバイスではそのスクロールの後に慣性を再現しているため、jQueryのスクロールイベントがものっそい発火します。
これに対して、 Promo/wheel-indicator が役に立ちました。
MacBook ProやThinkPad X220で試しましたが、良い感じにトラックパッドの問題を吸収してくれました。是非使ってみてください。
スマートフォンのスワイプ
スクロールイベントを受け付けない設定にしたら、スマフォでの操作が一切できなくなりました。(笑)
多くの場所で話題にされているように、モバイルアクセス率は年々増え、このページの趣旨としても特に若者がスマートフォンで閲覧しに来るというケースが多くを占めると思っていますので、なんとかしなければいけません。この問題には、次の qiita:Wataru さんの記事が役立ちました。
記事では横スワイプのハンドリングとしていますが、これをXからYに変えるだけで縦スワイプに対応することができました。
ほかにもいろいろやったことはありますが、とりあえずこんな感じで
OGP
OGPとは Open Graph Protocol の略で、シェアされた時の文言やプライマリーとしてSNS側に差し出す画像を設定することができます。これはHTMLファイルのmetaタグで行います。細かい内容は割愛します。
設定が終了したら、ためしにFacebookの OGP Debugger にかけてみます。
正しい内容が表示されました!
これから
今回はjQueryを主に使ってティザーサイトを制作しました。
jQueryは長く使われ続けている、いうところの「枯れた技術」です。
JavaScriptのライブラリで、最近名を広めているものに React があります。Reactを使うと、ユーザインタフェースをコンポーネントベースで管理でき、情報がリアルタイムで伝播していくという強みがあります。とはいえ、この規模のコードベースにReactを使う必要性はあまり高くはないということを友人のごちうさ勢から聞き、またReact + ReactDOM自体の容量がjQueryに対して肥大であるという点も導入の障壁であるということでした。
これに対して、クラスベースで管理していくことは一つのベストプラクティスであるという話も友人のNEW GAME!勢から聞きました。ノンフレームワークで作っていったので責務があやふやだったり「あれどこに書いたんだっけ」ということが頻発しました。クラスベースで設計することでこれが少しは楽になるのではという展望があります。
これからも、自分自身で自分のプロダクトのWebサイトやマーケティングの舵を切りながら、幅広い知識を身につけていきたいと思っています。
Safari Extensions + Sinatraを使ってYouTubeの画面上にワンクリックでmp3でダウンロードするボタンを生やす
Safari Extensions を使ってYouTubeにワンクリックでmp3でDLするボタンを生やすことに挑戦してみました。
YouTubeのページ内に出現する動画へのリンクやプレイヤーの近くにmp3でダウンロードする動線を追加してみます。
リンクをクリックするとローカルに立てたサーバーがyoutube-dlコマンドをたたき、デスクトップにmp3ファイルを保存します。
スクリーンショット
トップページ
検索結果
プレイヤー
実装
まず、youtube-dl をインストールします。
gist969d51740bf7d7d7fb633874971482c9
YouTube-dlの基本的な使い方は以下です。
gist5aac96730ecc9e487bc0bcf6a379da08
Safari Extension
まず、Safari Extensionを使って、ページ内の各動画のプレイヤーやリンクの近くにmp3ダウンロード用の動線を生やします。
リンク先は後述するサーバーで、パラメータとして動画IDを渡していきます。
- デベロッパーツールのExtension Builderを開く
- 左下のNew Extensionを押して適当な場所にExtensionを初期化
- 対象URLを追加して www.youtube.comにする
- Secure URLでも実行にチェックを入れる
- jQueryを落としてくるか、Extensionのディレクトリでyarn init→yarn add jqueryする
- ページを開く前に実行するJavaScriptのところにjquery.min.jsいれる
- ページを開いた後に実行するJavaScriptのところにindex.jsいれる
コードはこんな感じ
gist49f15f60edbdc76b1d7b246068a54cd1
証明書らへんはちょっとよくわからなかったのでうまく動かない方は他を参照してみてください。
サーバ側
youtube-dlコマンドをたたくためだけのサーバを立ててそこにvideo IDを伝えるようにします。
今回はSinatraを使います。
常に立てておくと他のアプリ開発のときにポートが被って邪魔なので、適当に4568とかに変えておきます。
サーバにアクセスしたくなったたびにターミナルを立てるコマンドを打つのは面倒なので、リクエストが飛んできたら勝手に立つようにしたいです。
おそらくPowなどを使って実現できると思っています。
コード例
gistc043caef6f6de2082a9d22d8dfbb61d8
ruby server.rb でサーバを立てます。
これで、リンクをクリックするとサーバーに定義しておいたコマンドが走り出し、終了するとブラウザに標準出力が表示されます。
今回制作したスクリプトのソースはこちらにあります。
クリエイティビティのジャイアニズム/CGMの受け手にあると良さげな「ツボのダイバーシティ」
ここにボーカロイドの樹というものがあると仮定します。クリエイターがこの樹にできる動作は「(樹高を)伸ばす」か「(新しい枝を)生やす」かのどちらかであるとすると、ryoさんのメルトやkzさんのpackagedは新しい枝を「生やした」、というか年輪の一番ど真ん中を形作りました。毎年wowakaさんやハチさんやDECOさんがその樹を「伸ばし」て、オワタPさんやアゴアニキPさん、ほぼ日Pさんたちは「枝を生やした」。そして2017年にこの樹を俯瞰すると、中心にズシンと芯の通った「ボカロ的」という概念と、そこから枝を分けるたくさんの「準ボカロ的」コンテキストがこんにちも豊かに実を作り続けているということだと思います。
もちろんナユタン星人さんはすごいし、ナブナさんもOrangestarさんもすごい、1年で何人か出て来る「20XX年のボカロP三銃士」みたいなのは、このボカロの樹の「年輪」となっていく人たちだと思っています。そしてここが僕のあまり好きじゃないところなのだけれど、ボカロ界隈は年輪「だけ」を心待ちにしているような節を感じます。錆び剥げていく僕達のコモンセンスをきちんと繋ぎとめてくれたのは「アンドロメダアンドロメダ」だったし「夜明けと蛍」のようなクリエイティビティだったのだけれど、ここではこのトップ曲群をある種のボカロ音楽のジャイアニズム的思想の結露と位置づけたいと思います。
ちなみに音楽的ジャイアニズムの権化は音ゲー界にあると思います。端的にいうと、速くすればいい、エモくすればいい。とにかくどれだけ肉汁のジュワっと出てコシの良いハンバーグを作れるかの競争がそこでは行われています。
僕もその実中高生ぐらいの頃は無心のなかで「ボカロの樹の年輪」になりたいと思って活動をしてきました。
でも、今は ジャイアニズム的な背比べから少し外れた場所にいたいんですよね。
リアル世界のアーティストでいうと、奥華子的であったり、くるり的であったり、やくしまるえつこ(相対性理論)的であったり。
コンテキストが複雑になりすぎて、僕達にはもうナユタン星人さんとナブナさんとOrangestarさんぐらいしか共通のコンテキストがなくなっていく。そういったジャイアニズム的年輪の追加ではなく、何か「新たな枝」を生やすというか、横へのうまい具合のピボットができないかというところを模索しています。だから今はポストアゴアニキPであったりポストほぼ日Pみたいな人をガンガンプッシュしていって、横の広がりが見えないと、ボカロもどんどん一番美味しいハンバーグを作った人が勝ちの世界になってしまうという気がしています。勿論それはスポ根的で賑やかなコミュニティで良いのだけれど、受け手としても、ツボというか、ストライクゾーンのダイバーシティを拡張していくと良いのではないかな?という気がしています。あれだけゼロ年代にたくさんの表現が生まれたボカロ界隈ですから、一〇年代はそれがますます広がっていくということです。そういった時代に、一つの表現や尺度に執着することなく、日々多様な表現を受け入れるマインドがあると良さげな気がしています。
自分が昼の世界で佇んでいるソフトウェアエンジニアリングの世界でも、アプリケーション、インフラ、ネイティブ(アプリのこと)とかいろいろコンテキストがあって、それぞれに豊かなアプリケーションやら設計思想やらコミュニティやらが実っているわけで、ボカロ界隈の飽和しきった(UTAUもCeVIOもあるぞ)コンテキストをひっくるめて今年の再生数上位3人、みたいな情報量の低いまとめ方は面白みはなくなっていくかと思います。今日のところは以上です。
ひさびさの新曲「birthday」でセルフ一問一答ライナーノーツ
いやー作ったねえ。
作るときは毎回一瞬なんだよね。
# 曲名の由来は?
11月3日の誕生日にループと歌詞だけできたまま放置してた
# これはどんな曲?
鎖国して自分のカルチャーに引きこもりますハイみなさんさようならって曲。
ほら江戸幕府も400年ぐらい鎖国してたんだから僕だって20代のチョットぐらい何も取り入れなくたっていいでしょ
# Bメロのラララーのやつなんなの
Bメロには歌詞があるやろという縛りから自由になりたいと思った結果非言語になった。
# ギターの音良くなったね
そうなんだよRealLPCをポチってしまったよ~~~~~
あとSquierのストラトキャスター買ったんで練習してます。3年後くらいには僕の曲は全部生ギターになっている。
# 音の抜け良くなったね
そうなんだよFOSTEXのPM0.3b買ったんだよ~~~~~
スピーカーがあると「クソな音像が作れなくなる」ね。今までiPhoneのイヤホンだけで全部完パケしてたけどやっぱ限界があったということですね。
ってことでオーディオインタフェースとか音ネタなんかよりまっ先にスピーカー買っときゃ良かったって今めっちゃ反省中。
あと独居始まって勝手に音出せる環境になったから音を確かめられる時間が増えたってのもある。
# 曲微妙じゃない?
今年の目標:クソ悩んで100点を1曲作るより能天気に50点を100曲作る
# 去年何してたの
社畜してました。
# 今年何するの
なんとしても去年の怠惰を返上するためにアルバム2枚出します
MonstercatのネットDJイベントがおもろい話(今更)
DTM Advent Calendar 2016の22日目の記事です
最近見つけたおもろいネットイベントにMonsterCharityがある、三行でいうと
・カナダのバンクーバーを拠点とするネットレーベルMonsterCatが
・Child's Playという慈善団体とのコラボで
・MineCraft上でDJイベントをやってた
ってやつなんですけど、これが音楽を通した社会貢献っていう枠と、MineCraftでのネットイベントっていう面白さがクロスしてすげー良さげだなあ。っていうのを思いました。とりあえずこれを見てくれ。