Terrarium

いわゆる掃き溜めの ありふれた有象無象

クリップボードの内容を勝手に使ってくれるシェルコマンドの自作

Problems

何かをコピーしてそれをターミナルのコマンドの引数として貼り付けて何かを実行させる処理をなんどもやるのは面倒. リストとなるテキストやCSVを作るほどのことではないが面倒.

Solution

クリップボードの内容を勝手に引数に入れてくれるようなシェルコマンドを作ればいい!!!

注意:Macを想定しています(pbpasteがある環境のみ)

...
youdl ()
{
    youtube-dl -f mp4 `pbpaste`
}

Conclusion

リンクをコピーしてyoudlと叩くだけで良く,これまでの「ペーストしてからダブルクォーテーションで囲む」作業が要らなくなり非常に楽になった.

これを思いついた時「天才かよ!」と思ってしまったので投稿しました… ん?よく考えたら関数にする必要ないし.zshrcに書かずともこれを実行してCtrl+Rで呼び出すだけで良いのでは…?

(ダウンロードした動画は私的使用の範囲内で使いましょう)

Storyboardとxibを使ってViewを小分けで管理する

はじめに

iOS(に限りませんが)でアプリ開発をしている際に,画面にでてくるコンポーネントをそれぞれ個別で設定したい場合がほとんどです. 画面内に複数のViewがある際に,それぞれのViewをxibで記載し,それをStoryboardにまとめる,という方法を使うことでViewの管理が楽になりそうなのでメモとして残しておきます.

TL;DR

  • アプリ内の各画面はStoryboardで管理
  • 細かいViewはxibでデザインを,UIViewクラスでoutlet経由でViewの見た目を管理する
    • File's Ownerに適切にclassを設定する
  • StoryboardにViewコンポーネントを配置し,Custom Classを設定
  • ViewControllerにViewをOutletで紐付けすることで,Viewの管理が可能

方法

1. View1の要素をxibで作成する

「NewFile」から「View」を選ぶとxibファイルが作成できます.

f:id:tellusium:20180927093328p:plain
Viewを選ぶとxibファイルが作成できる

このViewはラベルが2つあるので,それぞれConstraintをつけつつ配置します. 名前はTopView.xibとしました.

f:id:tellusium:20180927093439p:plain
ラベルを2つ配置したxib

ちなみにSimulated MetricsのSizeをFreedomにするとこの表示上でのサイズを可変できます.

f:id:tellusium:20180927093915p:plain
Freedomにするとサイズが可変可能

2. 上で作成したxibを持つUIViewのクラスを作成する

xibは見た目のみなので,それを持つUIViewのクラスを作り外部から扱いやすいようにします. 名前はTopView.swiftとしました. xibからViewの情報を取得し,addSubVIewします. この辺りの処理は以下のサイトを参考にさせていただきました.

【iOS】【swift】カスタムViewとxibを紐付ける - tanihiro.log

Swift3 [XIBファイル] コードでの呼び出し方まとめ – RE:ENGINES

xibで作ったCustomViewをStoryboardで使う

import UIKit

@IBDesignable
class TopView: UIView {

    // この2つは後のステップで追加する
    @IBOutlet weak var leftLabel: UILabel!
    @IBOutlet weak var rightLabel: UILabel!
    
    override init(frame: CGRect){
        super.init(frame: frame)
        loadNib()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        loadNib()
    }
    
    func loadNib(){
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "TopView", bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
        view.frame = self.bounds
        // viewのbackgroundColorはここで設定する必要がある
        view.backgroundColor = UIColor.cyan
        self.addSubview(view)
    }

    // viewの設定
    func setup() {
        self.leftLabel.text = "left"
        self.rightLabel.text = "right"
        self.rightLabel.textColor = UIColor.red
    }
}

3. xibのFile's ownerにCustom Classを指定

先ほど作成したxibファイルのFile's ownerにCustom ClassにTopViewクラスを指定します.

f:id:tellusium:20180930171117p:plain
File's ownerのCustom class

f:id:tellusium:20180930171121p:plain
File's ownerのclass

ViewのCustom classの方に設定するとEXC_BAD_ACCESSで落ちます. この回答を見ると書いてある(よくわかってはいないのですが,型周りの不一致らへんが原因なのかなと考えています…)

ios - Instantiate view from nib throws error - Stack Overflow

f:id:tellusium:20180930171244p:plain
ViewのCustom classを設定するのは🙅‍♀️

4. IBOutletで紐付け

File's ownerのCustom Classの設定が終わるとxibからTopView.swiftの方にIBOutletをつけることが可能になります. 2つのラベルのOutletを設置します.

5. アプリに表示する画面であるViewController,Storyboardを用意する

MainViewControllerという名前でViewControllerを,同様の名前でStoryboardを作成します. Storyboardでは,Viewコンポーネントを配置し,Custom classにTopViewを指定すると,ラベル等々描画されるはず… MainViewControllerにはOutletでViewを紐付け,TopViewsetup()を呼ぶようにします.

class MainViewController: UIViewController {

    @IBOutlet weak var topView: TopView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        topView.setup()
    }
    ...

f:id:tellusium:20180930174011p:plain
MainViewController.storyboard

結果の画面は↓↓↓

f:id:tellusium:20180930183123p:plain
結果

終わりに

エラーなどを調べているうちに全く同じ方法をしている記事を見つけました. こちらも参考に.

qiita.com

この記事の新規性はあまりないですが,additionalな情報をいくつか加えているのでそれでいいということで…

サイボウズのサマーインターンシップに参加してきました

2018/08/20 - 08/24の5日間,サイボウズ株式会社のサマーインターンシップに参加してきました.

cybozu.co.jp

私が参加したのは,モバイルアプリ開発を行うモバイルアプリケーションコースでした. 5日間という短い期間でしたが,サイボウズの開発の流れや会社の雰囲気を十分体感することができたと思います. 今後参加される方への参考になれば.

やったこと

サイボウズではkintoneというビジネス向けのアプリケーションを簡単に作成できるプラットフォームサービスを作っています. 今回はその関係の新規アプリを製作しているとのことで,その機能の実装を行いました. モバイルコースでは,各自が各々のタスクを持つのではなく,チームで手分けして機能を実装していくというスタイルでした.

初日

サイボウズのオフィスは,入り口に動物園があります.

f:id:tellusium:20180902140449p:plain
キリントーンと撮ったプロフィール写真

こんな感じのプロフィール写真を撮った後に,午前中を使ってセキュリティの講習会がありました. 様々な顧客のデータを扱うサービスということで,サイボウズのセキュリティ意識の高さが伺えました.

午後からは配属されるチームごとに分かれ,環境構築を行った後,いよいよ開発に入ります. といってもいきなり実装…ではなく,まずは開発する機能の詳細を決める全員でのMTGがありました. アプリ開発ではスクラム開発を採用しているそうので,スプリントのプランニングや,機能のデザインや実装の詳細をあらかじめ決めてから実装に入ります.

2日目

昨日に決めた詳細を元に,実装を行なっていきます. まずはアプリの仕様を把握するため,チームでモブプロを行いました.

午後はタスクの振り分けを行い,各自実装をはじめました. 開発しているアプリはクリーンアーキテクチャを採用しているそうで,ModelやView,ViewModelや通信周りなど,非常に多くの要素から構成されていました. コードの行数が多く,どこを編集するべきかを探すのが大変で,それだけで結構時間がかかったように思います. とはいえ,役割ごとに場所が異なっているため,そのイメージがつかめればすんなりと読めた気がします. アーキテクチャを採用する利点ですね.

3日目

スクラム開発ということで,15分ほどのデイリースクラムを行いました. 何をしているか,何をやったか,問題は何か,をまとめて各自発表していきました.

その後は引き続き開発です. 私が担当していた部分は比較的簡単だったため,この日には最初に与えられたタスクは実装が終わりました.

4日目

全員で最初にあったタスクはほぼ終わりそうだったため,追加の機能実装をすることになりました. 今回の機能は最初のものよりも難易度が高く,ModelからViewまで全てを編集していく必要がありました. ここで(私の担当分では)初めてRxSwiftが登場し,その概念に悩みながら実装をしていきました. (中身の値をprintする方法がわからなかったり,onNextを実行した後でonCompletedを呼び忘れ次の担当にバグを残してしまうなど…)

5日目

午後から成果発表会だったのですが,まだ上の機能の実装が終わっていなかったため,スライド作成と並行して実装をしていました. なんとか(仕様を満たし切ってはいないが)動作するところまでは完成し,発表会でデモを行うことができました.

学べたこと

  • サイボウズの開発スタイルである,スクラム開発やスプリントプランニングなどを体験できた
    • 全員で詳細を決めるのはとても大事だと思った
  • きちんとしたアーキテクチャで書かれたコードを読んでいく経験ができた
    • 今後アプリを作っていく際の参考にできた
  • 働きやすいと言われるサイボウズの社風を感じることができた
    • 社員さんの様々な話をお聞きすることができた
    • 働き方の自由度が非常に高かった

まとめ

5日間と短い期間でしたが,最終日にはこれで終わってしまうのが残念で,次週以降も引き続き開発を続けたくなるインターンシップでした. 最後になりましたが,指導をしてくださったメンターの方々,ランチなどご一緒したモバイルチームの方々,サイボウズ株式会社の皆様,そしてインターンの同期の方々,ありがとうございました 🙇‍♂️

f:id:tellusium:20180902143458p:plain
作業中

CEDEC2018の講演を聴いた感想(タイムシフト)

CEDEC2018

国内最大レベルのゲーム開発者カンファレンス,CEDEC2018のタイムシフトパスを購入し,いくつか講演を聞きました. https://2018.cedec.cesa.or.jp/ 去年のCEDECゼルダの講演でCEDECの存在を知り,今年申し込んで見たという感じです.

その中でも興味のある講演をいくつか聴いたので内容をまとめました.

明快で軽快なUI『Nintendo Switch 本体機能』の制作事例

https://2018.cedec.cesa.or.jp/session/detail/s5abdde297aa0e

任天堂の方々による講演です. NintendoSwitchにおける本体機能のUIをどう作ったか,ということに関するものでした.

良い例と悪い例の具体的な例があり,とてもわかりやすい講演でした. ポイントは次の通り.

  • WiiUまでは多機能であることを重視していたが,現在はスマートフォンなど似たデバイスは溢れている
  • そこで,「ゲームで遊ぶこと」に特化するUIを作るため
    • 圧倒的に明快にする
      • 簡単そうと思ってもらう
        • ゲームやサービスを「混ぜない」ようにする
        • 主役であるゲームの「アイコンを大きく」「絵の密度を大きく」
        • 他の機能も直感的に使えるよう「上下の意識」
          • 上がマクロ,下がミクロ
        • 数を少なく見せるために「グルーピング」
      • ガイドラインを迷わないようにする
        • 迷いそうなルールの例
          • カーソルの選択においてどのボタンに移るか?
            • 基本的にはボタン配置をグリッドに固定した
          • どの種類の効果音を使うか?
            • 「案内」と「消去」でそれぞれ作っても,じゃあ「終了」はどっち?となる
            • 効果音の種類を「正常系」「エラー系」「警告」の3つに制限
            • 視覚と聴覚を一致させるよう見た目も統一
    • 圧倒的に軽快にする
      • UIにかかる時間をできる限り削る
      • 車が停止する流れと同様,「ユーザの理解」「ボタンの操作」「システムの処理」の3つのフェーズが存在
      • これらの合計がUIにかかる時間
        • システムの処理
          • リソース読み込みを極限まで減らした
          • アニメーションをゼロにしたらどうか?
            • そのままだと何が起きたかわからないので,0.2s程度に
        • ボタンの操作
          • カーソルの初期位置を確定とキャンセルどちらにするか
          • 確定側にすることでユーザの操作数を減らした
          • 基本ユーザの操作を「信頼」し,確認は「端的」に行うように
            • 良いコミュニケーション
        • ユーザの理解 = 発見の速さ
          • アイコンは必要か?
            • Switchでは言葉のみにした
            • ダイアログが出ると,ユーザはその言葉を頼りに探す
            • アイコンがあるとアイコンを見てしまうが,わかりづらいアイコンがあるとアイコン → 文章という目の動きが発生してしまう
          • 斜め読みしやすい文章にした
            • 左上と右下だけ読めば何をすれば良いかわかるように
    • 快適にする
      • これまでは不快を減らす話,これは快を増やす話
      • 操作音の心地よさを生み出す方法
        • 移動:ボタンの種類で音を分けた
        • 決定:いくつか種類があるが,「カチッ」のうち「カ」と「チ」のテンポを揃えることで連続操作でも違和感がないように
        • 遷移
          • 遷移前には「繊維するよ」遷移後には「遷移したよ」と音のつながりを作った
          • 画像への遷移時には画像を選択する音に似た遷移音,設定への遷移時には設定の選択時の歯車音を使った遷移音を採用
      • 触りたいを作る

「どこから作ればいいんだろう?から10年」

https://2018.cedec.cesa.or.jp/session/detail/s5b1e23aaede0a

任天堂代表取締役・フェローの宮本さんの講演. 基調講演であり,10年を振り返りながら話すスタイルでした. BotWをはじめとするゴールが明確でないゲームやモバイルの普及による課金型ゲームについての話などでした. 詳細は割愛.

ワンランク上のゲームデザインレベルデザイン・UIデザインを考える 「コンテキスト」「コンフリクト」「コントラスト」デザイン

https://2018.cedec.cesa.or.jp/session/detail/s5ac06de06756a

Slideshare↓↓↓

ワンランク上のゲームデザイン・レベルデザイン・UIデザインを考える 「コンテキスト」「コンフリクト」「コントラスト」デザイン

Unity Technologies の大野さんの講演. ゲームデザイン系の講演を初めて聞くのでとても面白かったです.

  • コントラスト
    • 難易度などにメリハリをつける
    • 線形にあげるのではなく,上下させたり急にあげたり
    • 詳しくは昔のセッション参照
  • コンテキスト
    • プレイスタイルやゲームに必要な知識,操作方法など
    • ハイコンテキストとローコンテキストがマッチしていない事例
      • ゲームが面白くない
        • コンテキストの相性が悪い可能性
          • モバイル・コンシューマ・PCのプレイスタイルの違い
      • 新しいゲームシステムを作ったが評価が悪い
        • コンテキストのレベルが悪い
          • 売れるゲームは入り口がローコンテキスト(前提知識不要)出口がハイコンテキスト(奥深い)
            • 徐々に狭まるのが良い
          • 新しい要素を入れると急にローコンテキストやハイコンテキストになる恐れ
  • コンフリクト
    • プレイヤーの目標達成を妨げるもの
    • 種類
      • 接近・接近:どっちにするか
      • 回避・回避こっちもダメ,あっちもダメ
      • 接近・回避:これはいいけどこっちはだめ
    • 複数のことを同時にやらせるとコンフリクトが起こる
      • 自発的:ユーザが選択可能
        • 敵の奥の宝箱
      • 強制的:選択不能
        • ボス線
    • ゲームのコンフリクト
      • 目的のコンフリクト(クリア or ハイスコアetc)
      • 敵のコンフリクト(どれから倒すか? etc)
      • 行動のコンフリクト(宝箱を取りに行く or 先に行く etc)
      • 選択のコンフリクト(どちらの道を選ぶか,選択肢が多すぎるとストレスになる)
      • 消費のコンフリクト(このアイテムを使うか否か)
  • ゲームは人生に必要か?
    • YESと考えている
    • プレイヤーの本質を自己確認できる
      • メディアで唯一?

コンフリクト周りの話はこれまでプレイしてきたゲームを考えても納得する内容でした. 任天堂はこれを作るのがとても上手だそうな.

フィールドとモンスターの制作工程から読み解く「モンスターハンター:ワールド」のゲームデザイン

https://2018.cedec.cesa.or.jp/session/detail/s5abe362fd7694

株式会社カプコンの徳田さんの講演. モンハンはプレイしたことがない(やりたい)のですが,モンハンという世界を作る裏側のような内容でした.

  • MHWのミッション
    • 初めての人でも楽しめる(シリーズの知識を必要としない)ため新大陸に
    • オープンフィールド
      • 広さではなく密度を重視
  • フィールドのレベル設計
    • 序盤:古代樹の森
      • 森なのでわかりやすい,難易度が高いところは湿度を高めにしてヤバさをわかりやすく
    • 瘴気の谷
      • 竜の墓場,エネルギーを求めるモンスターが集まる
    • 大蟻塚の荒地
      • ワイド感を表現
    • 中盤:陸珊瑚の台地
      • 歴代にはない驚きを与えるためのフィールド
        • 慣れているユーザにも驚いてもらう
      • 陸珊瑚というファンタジー要素
    • 終盤:龍結晶の地
      • 古竜の集まるボスMAP
  • モンスターの作り方
    • モンスター=プレイヤーを適度に追い詰めて,倒した後に気持ちよくなる存在
    • 何度戦っても,どの武器で戦っても面白いようなモンスター
    • モンスターづくりの2大ポイント
      • インパク
        • 感情を動かすことで倒した後の気持ち良さを増幅させる
    • 攻略
      • プレイヤーに選択肢を持たせ,何度遊んでも新たなアクションの可能性が生まれるようにする

上のゲームデザインの講演を聞いた後だったので,なるほどなぁと思える内容も多かったように思います. アクションの可能性とかもコンフリクトの一つであり,うまく選択肢を選ぶと報酬(短いタイムetc)が得られたり. 基本的にはローコンテキストでありながら,中盤に新しい内容を持たせることでハイコンテキストに. 最後がボスマップなのはお決まりなんでしょう(多分) ゲームを作ってみたくなる…

終わりに

ゲームデザインって面白いですね. というか設計行為自体がやっぱり面白い. ゲームに限らず,アプリのアーキテクチャとか. 時間がない中タイムシフトでみたのですがまあこれだけ見れれば元が取れたかなという感じ. (欲を言えばもうちょい任天堂の講演を聴きたかった…)