読者です 読者をやめる 読者になる 読者になる

イッツァハローワールド

恥さらしていこうかなとか。

ざっくりーのWATCH対応をしてみました。

iOS WATCH

ひと月以上前に書いた記事を発掘しました。

WATCH買いました。

先日秋葉原ヨドバシでWATCH買いました。以外と在庫あるのね。
https://instagram.com/p/2P7bVgqMro/

なんで38mm選んだのか、なんでよりによってピンクなのか、自分でも謎です。
ほんとは42mmで黒バンドとかが良かったんだけど、案の定予約が必要だったのでした。
しかし転職にあたりキヤイを入れるため(?)にすぐに手に入るウヲッチを購入した次第です。

二日三日つけているけど、あんまり気にならなくなってきましたw

自作アプリのウヲッチ対応をしてみた。

ウヲッチを買ったので、自作アプリざっくりーのウヲッチ対応をやりました。

ざっくりーについてhanamiju.hatenablog.com

もともと、簡単操作でグルメ検索してみたいアプリだったので、iPhone版をそのまま移植しました。
加えて、Handoffつかって、ウヲッチでみているお店情報の詳細をiPhone側で見ようとさせています。

f:id:hanamiju:20150507023508p:plain

簡単にだけど、WatchKitをかいつまんで覚えました。
つぎは、watch os2用になんかクソアプリ考えたいです。

ランディングページ

zakkly.instapage.com

xibを使ってソースコードから表示しようとした時にapplicationDidFinishLaunchingが呼ばれなくて困った話(OS X App)

OSX swift

最近は上京してOSX Appを書いている人です。

困りごと(ていうか届かぬ文句)

  • AppKitまわりの資料が少ない
  • AppKitまわりの資料が古い
  • ↑探すくらいならリファリンス読む
  • Swiftとの合わせ技だとめったにない
  • xibとかの話だとあるわけがない

今回の現象

作りたかったもの

  • OS Xアプリで簡易WebブラウザみたいなWindowにWebView乗っけただけのもの。
  • NSWindowControllerでWindowおよびその上のViewイベントの管理をする。
  • 新しいウィンドウを開くみたいなリンクをクリックしたら新しいWindowControllerを生成する。
  • WindowControllerは管理クラスが管理して、Windowを閉じたら管理クラスから抹殺する。
  • WindowControllerの動きは共通かつ、Window内でViewの遷移がないからStoryBoardは使わずxibを使う。

f:id:hanamiju:20150526005540p:plain

やったこと

  • StoryBoardファイルは消す
  • NSWindowControllerがFiles Ownerのxib(CustomWindow.xib)を作る
  • プロジェクト設定のDeployment Info - Main Interfaceを消す
  • AppDelegateのapplicationDidFinishLaunchingで↑のxibからWindowControllerのカスタムクラスを生成
func applicationDidFinishLaunching(notification: NSNotification) {
        var windowController CustomWindowController:  = CustomWindowController(windowNibName: "CustomWindow")
        //...
        self.window = windowController!.window
        self.window!.setFrame(NSScreen.mainScreen()!.frame, display: true, animate: true)
        self.window!.makeKeyWindow()
    }
  • windowDidLoadで管理クラスにWindowControllerを保存、windowWillCloseで管理クラスから削除

ビルド結果

Windowが表示されない。
ていうか、AppDelegateのapplicationDidFinishLaunchingが呼ばれないからWindowが生成されない。

AppDelegateのクラスの宣言時に@NSApplicationMain書けば(デフォルトで書いてあるけど)applicationDidFinishLaunchingが呼ばれると思っていたんだけど違うらしい。

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
// ...

解決策(スマートではないと思うけど...)

要はapplicationDidFinishLaunchingが呼ばれれば良い。

  • 空のMainMenu.xibを用意する。

f:id:hanamiju:20150526011522p:plain 

  • Files Owner(NSApplication)とAppDelegateをDelegateで結ぶ
  • プロジェクト設定のDeployment Info - Main InterfaceをMainMenuと入れる

まとめ

  • だいぶ特殊用途だと思うけど、今回はこんな感じで解決した。
  • すげー時間かかった。空のNib作らなくてもいける方法ある気がしたけど、今回はタイムアップでした。
  • 今回初めてNSWindowController使った。
  • Viewの切り替えがなかったからNSViewController使わなかった。
  • いっぱいWindowあって、いっぱいViewを切り替えるアプリを作るのは骨だなあと思った。

祝 LINEスタンプ発売されました「真顔くん」

Lineスタンプ

先日(つっても結構前)につくったLINEスタンプが発売されました。

store.line.me

私の精神性を表したようなラインナップとなっております。
f:id:hanamiju:20150516174716p:plain

歩み

絵を描くのが苦手(めんどう)な人がLINEスタンプ発売するために、
どのくらい手を抜いていいものか検証していたんですけど、まさかここまで時間がかかるとは...

  • 2014/11/16 一晩で製作・申請
  • 2014/12/09 リジェクト
  • 2015/02/13 修正版を申請
  • 2015/05/15 申請通過・発売

作業時間

20hくらい

内訳

  • 文言を考える ... 3h
  • 絵の練習 ... 3h
  • 下書き、清書、Illustatorで画像作成 ... 6h
  • 修正 ... 8h

登場人物や体のパーツを使いまわしたのでこんなもんですみましたが、ちゃんと絵を描いてスタンプごと被らないようにしたければこの数倍はかかるんじゃないかという印象です。

宣伝

いろいろ方法あります。

SNSつかう

スタンプ画像あるとより効果的。
私はtwitter, Facebookに投稿しました。


口コミ

社長に「今日LINEスタンプリリースしました〜!」って言ったら、速攻slackでブロードキャストされました...
宣伝効果抜群。

みんなに使ってもらう

使い勝手がよければ、伝染して欲しくなるはずって信じています。
今回作ったやつは使い勝手いいと信じているのですが、みんなこれ使い始めるとLINEが泥沼化する気がしないでもありません。

これから

スタンプの管理ページからいろんなデータが見れます。

  • 売上レポート
  • スタンプの送受信数

などなど。

スタンプごとの送信、受信の数が見れますのでみんなこんな辛辣な言葉投げてんのか...と心が少し痛くなったりならなかったり。

あんまり使われていないスタンプの修正を試みたりはやっていこうかなと思います。

あと、宇宙人のスタンプが↓のときからリジェクトされたままになっているので時間のあるときに修正しようかなとか。hanamiju.hatenablog.com

過去記事たち

hanamiju.hatenablog.com
hanamiju.hatenablog.com
hanamiju.hatenablog.com

Handoffしようとして、Activityの引き継ぎがうまくいかなかったときの話

iOS

WATCHが発売されたので、ウヲッチの実装を実機で動作確認できるようになりました。

Handoffまわりとかシミュレータで動作確認できないので、まあ動いているだろうでコードを書いてはみたのですが実機で動作確認してみたら見事に動いていませんでしたw

そんな、私のための備忘録です。

現象

WATCHで表示していた情報をiPhone側に引き継いで表示させようとしたが、意図したViewが生成できず表示ができなかった。

処理のフロー

  1. ウヲッチからiPhoneにupdateUserActivity:userInfo:webpageURL で通知を実施
  2. application:continueUserActivity:restorationHandler:が呼ばれない→iPhone側が意図した動作をしない
  3. ↑のかわりにapplication:didFailToContinueUserActivityWithType:error:が呼ばれる

エラー内容

Error Domain=NSCocoaErrorDomain Code=4611 "操作を完了できませんでした。(Cocoa エラー 4611。)" UserInfo=0x17006c0c0 {NSUnderlyingError=0x174246540 "操作を完了できませんでした。(LSContinuityErrorDomain エラー -110。)"}

原因

エラーコードの調べ方から調べましたが、どうやら4611はNSUserActivityHandoffUserInfoTooLargeErrorでUserInfoのデータサイズがでかすぎるらしい。

エラーコードの調べ方

NSError コードの調べ方 - 日々是笑心

というわけで

UserInfoの内容を小さく作ったらちゃんと動きました。ばんざい。



エラーコード4611は全然ググっても出てこなかったから、だいぶ詰まりました。
これからはちゃんとエラーコードも見ます。

swift1日目

勉強 swift

今までswiftから逃げまわってきた人ですが、
先日先輩からswiftの書籍をもらったので、勉強メモ。

たのしいSwiftプログラミング―[iOS 8&Xcode 6対応]

たのしいSwiftプログラミング―[iOS 8&Xcode 6対応]


C言語わかる、Obj-Cもかじっている程度なら全然分かるメモかと思います。

swiftやる前にPlayground

その名の通り、swiftプログラムの遊び場、実験場。
テキストエディタswiftコードを書くと実行結果を表示する。
Xcodeにあるの知らなかったぜ...

Playgroundファイル作成

[File]→[New]→[Playground...]でつくる。

変数宣言

var 変数: 型
// 例
var num: Int
num = 3

// 初期化
var num2: Int = 0

// 型推論
var num3 = 0.5 // 少数で初期化しているからDoubleと推論

慣れない('A`)
まずここから慣れるの時間かかるな...

定数宣言

let 定数: 型 =

定数は初期値が必要

// 定数宣言
let pi = 3.141592 //OK
pi = 3.1 //エラー(変数ちゃうで)
let root2: Double //エラー(初期値ないよ)

文字列

// 文字列
var emptyString = String()  // 空文字

var num1 = 1
var calcString = "1 + 1 = \(num1 + num1)"   // 文字列補間

文字コード→文字をつくる

// 「\u{文字コード}」で記述
let faceChar = "\u{1f617}"  // 😗

letで宣言すればNSString, varで宣言すればNSMutableString

なるほど。わかりやすい。

配列

// 配列
var year = [2010, 2011, 2012, 2013, 2014, 2015]

// 配列の型を明示的にする
// var 変数名:[型] = [要素, 要素, 要素]
var 都道府県:[String] = ["東京都", "京都府", "沖縄県"]

//空配列 (どの書き方でもいいよ)
var emptyArray = [String]()

var emptyArray2: [String] = Array()

// 配列の型推論
var emptyArray3 = []

辞書

// 辞書
var address = ["都道府県" : "東京都", "市区町村" : "渋谷区"]
// キー指定で値を引っ張る
var prefecture = address["都道府県"]

// 辞書の明示的型宣言
// var 変数名 = Dictionary<キーの型, 値の型>()
var emptyDict2 = Dictionary<String, String>()
// var 変数名 = [ キーの型 : 値の型 ]
var emptyDict3 = [Int:String]()

// 辞書の型推論
var emptyDict4 = [:]

NSArray と NSDictionary

  • NSArray ≠ Array
  • NSDictionary ≠ Dictionary
import Foundation

// Swiftの辞書作成
var dict = ["key": "value"]

// NSDictionary型の辞書として生成
var nsdict = dict as NSDictionary

関数

/*
func 関数名(引数名:引数型) -> 戻り値型 {
    処理
    return 戻り値
}
*/
func func1(x: Int) -> Int {
    return x + 7
}

func1(3) // 10
func1(2) // 9

クロージャ

ああ、Blocksのことですか。

/*
クロージャ
{ (引数名, ...) -> 戻り値型 in
    // 処理
    // return 戻り値
}
*/
// hoge関数の定義
func hoge(handler:(String, String, String) -> Int) {
    var hoge1 = "hage1"
    var hoge2 = "hage2"
    var hoge3 = "hage3"
    
    handler(hoge1, hoge2, hoge3)
    
}

// hoge関数を呼び出す
hoge({(hoge1 ,hoge2, hoge3) -> Int in
    println(hoge1)
    return 0
})

上記の例文でやっていることは

  1. hoge関数を呼び出す(引数にクロージャ
  2. hoge関数で定義したhoge1〜3をクロージャに渡す
  3. クロージャはhage1を出力, 0を返す

クラスと構造体の使い分け

  • 大量にインスタンスを確保、破棄するもの → 構造体
  • たくさんの情報を持っている、ライフタイムが長いもの → クラス

理由

構造体の方がクラスより軽量
  • インスタンスの確保、破棄に関する手間が少ない
  • メモリ量が少ない
構造体はARCが効かない

プロパティ

保持プロパティ

クラス、構造体の中で変数の形で宣言されているもの。
よく見てきたプロパティ。

算出プロパティ

変数を持たず、プロパティにアクセスするメソッドを用意して計算を行うもの。¥

struct Rect {
    // 保持プロパティ
    var x: Float = 0
    var y: Float = 0
    var width: Float = 0
    var height: Float = 0

    // 算出プロパティ
    var centerX: Float {
        get {
            return x + width * 0.5
        }
        set (centerX) {
            x = centerX - width * 0.5
        }
    }
}

プロパティ変更時に別のプロパティも変わらないといけない場合は、算出プロパティにしておけばいちいち全てのプロパティの変更処理書かなくていいから楽ね。

メソッド

タイプメソッド

Obj-Cでいうクラスメソッドのことかな。

  • 構造体のタイプメソッドはfuncの前に "static" をつける
  • クラスのタイプメソッドはfuncの前に "class" をつける

Optional型

  • Optional 型 : nil の代入を許す
  • 非 optional 型 : nil の代入を許さない

Any

なんでも指定できる。Any型の配列ならなんの型でもオーライ

    var anyArray = [Any]()
    anyArray.append(0)    // 整数
    anyArray.append(1.234)    // 小数
    anyArray.append("hoge")    // 文字列

AnyObject

id型とおんなじイメージ

ラップやらアンラップやら

  • ラップされてる状態 → オブジェクトが、正当なものかもしれないし、nilかもしれない状態。
  • アンラップする → どんなオブジェクト化を確定する。

ここは、もうちょっと勉強してからメモろう。

MetaType

オブジェクトの型

objective-cではオブジェクトのクラス名欲しい時に

Class objectType = [SomeClass class];  

ってやってたけど、swiftでは

var objectType = SomeClass.self

らしい。
Simple Reflection in Swift

感想

('A`)慣れねえ。(2回目)

Playgroundで試しながらの勉強なんで、理解度はいつもより早いんだけどね。
実際にサンプルプログラム書きがてら学ぼう...

iPhoneでお階段登りするために正月休み潰した話

iOS アプリ

先日アプリをリリースしました。

ってのを前の前くらいの記事でさらっと言ってたんですが、覚えているうちに製作時に思ったことや考えたことについて書きます。

お階段登りとは

  • iPhoneで擬似的に階段を登って高さを競うゲーム

その他機能

  • 階段は一段づつしか登れない
  • 課金すれば早くたくさん登れる
  • 自分の位置を有名な建築物、山などと比較して表示する。(キャプチャ付きで共有できる)
  • 他のユーザーの到達点に達したらすれ違える。
  • 他のユーザーをタップするとメッセージが出る。

ありがたいことにレビューいただいたサイトの説明がスッゲーわかりやすかったのでこちらもみてみてください。
お階段登り 〜昨日の俺とは数段違うぜ!〜|レーシング/レース|アプリ紹介|iPhoroid|iPhone&Androidゲームアプリの攻略サイト

紹介動画

ご丁寧に紹介動画も作りました。
これでアプリの世界観が伝われば嬉しいです。


お階段登り 使い方 - YouTube

AppStoreの説明動画に載せたんだけど、「もっとちゃんと説明しろ」ってリジェクトされました。
(ちゃんと説明してるつもりなのに。)

動機

正月休みの宿題として「ゲームを一本リリース(申請まで)する」を掲げました。
最初に考えたのが、SpriteKitをつかったゴルフゲーでした。基本機能はできてたんだけどゲームの構成とホールのバリエーション考えてたら2014年越しましたw

残り少ねえってことで、どうしようかと思っていたのですが
あと、↓の記事見てすっげえわかりやすくてくだらないゲーム作りたいって思ってクソゲー作りに着手しました。


「誰もやりたくないアプリ」を3日でつくったら、広告収益3,500万円超え。800万ダウンロードの無駄タップアプリ「100万のタマゴ」が世界各国でヒットするまで。 | アプリマーケティング研究所

名前の由来

戒壇廻りと語呂が似ているから(安直)
善光寺のお戒壇めぐり

ネタの構想

日常生活で特に意識せずやっていることをクローズアップすると逆に面白く見えるのではないかと考えた結果

  • 階段を登る
  • トイレットペーパーを巻く

がポンとでてきました。
トイレットペーパーを巻くアプリは結構あったのに比べて階段を登るのはほとんどなかったため、「これや!」ってなりました。

見た目で気をつけたこと

「くっだらないゲーム」を表現するために、見た目をチープにするように心がけました。
↓ゲーム画面
f:id:hanamiju:20150309230050p:plain

  • 色使いを頑張らない
    • 今回はモノトーン
  • 最小限の表現にする(必要以上に凝らない)
    • 動く/止まる は適当な集中線の有無のみで表現
  • 手書き調にする

なぜチープに見せるか

通常時はチープ装いをすることでサブ機能がギャップで映えて面白く見えるのかなとか考えました。

非現実な機能の場合

いろんな足音を選択できる→現実とのギャップ(なんで足音がピヨピヨやねんw)

現実にある機能の場合

上の段の人とすれちがう→チープなくせに妙なことできるっていうギャップ(なんで他のユーザーでてきてるねんw)


最後にチープすぎて意味わかんないものにならないように注意。

技術的に苦労したこと

  • アプリ内課金
  • Auto Layout

いいネタなのでまた別記事で。

技術的じゃないところで苦労したこと

  • 階段づくり(ここに一番時間かけた)

うすうすわかりそうだけど、どうやって階段のアニメーションを実現しているかは秘密で。実装自体はほとんど時間かかっていません。

UIづくり

ゲーム作りなので、極力iOSの標準UI使わないようにカスタムUIで実装しています。

素材作成

最近sketchを購入しましたので、練習がてら素材作成に使いました。

Sketch 3

Sketch 3

  • Bohemian Coding
  • グラフィック&デザイン
  • ¥9,800

sketch2ももってて使い方はだいたい知ってたんで簡単に使えました。
解像度違いの画像エクスポートがマジで楽。

横画面

指でスワイプできる面積をできるだけ広くしたかったので今回はじめて横画面で製作しました。
Auto Layoutで多デバイス対応するのが本当に骨が折れました...

Auto Layoutで工数かけたくなかったら画面設計時に縦横比に依存しないようにしたり縦横日を固定するよう配慮すべきと学びました。

工数

正月の宿題といいながら、休み中にできたのは1人で階段を登るところまでで、その他の実装、素材作り、サーバ作成込み込みで1月弱くらいかかったです。

今後の展望

いろいろ機能追加します。くだらないことを。

つくってみて

  • 軽い感じで設定した宿題のはずが、Auto Layoutやったり課金やったりサーバつくったりでわりと濃密になりました
  • 構想していたゲームがなかなかの再現度で実現できて嬉しいです
  • 一言で紹介できるアプリって覚えてもらいやすかったりいろいろ楽です

おまけ: 楽しいお階段登りの使い方

一番のヘビーユーザー(私)がお教えしましょう。

ブラインド登り

慣れると画面を見ずとも軽快に階段を登れるので、何かをしながらでもお階段登りができます。

リズムをとる

鈴、拍子木、木魚(7777段登ると使用可能)などの足音はリズムが取りやすいです。
加えて、地味にiPodの音楽鳴らしながらアプリがつかえるので、好きな音楽を聴きながら好きなリズムを奏でましょう。
1曲流すだけで数百段登れます。

木魚を操るコツは木魚6回→鐘1回のサイクルなので「ポク・ポク・ポク・ポク・ポク・ポク・ゴーン(2拍)」のリズムで奏でるのが良いでしょう

催眠効果

BGMを消して一定のリズムで階段を登ると超眠くなります。
私は何度か寝落ちしました。

最後に

ぜひやってみてレビュー欄荒らしてください!

Node.js + MongoDBでAPIサーバつくるまでに勉強したこと

node.js

前回の記事の補足記事です。

Node.js(restify) + MongoDB(mongoose) でAPIサーバつくってHerokuでデプロイするまで - イッツァハローワールド

勉強する前のレベル

カスレベル

  • Node.jsは昔ドットインストールしたことあったっけなってくらいの知識(概要は少し覚えてた)
  • JavaScript自体あんまり使わない
  • MongoDBってなに?マンゴー?

Node.jsの知識

基礎はググるよりも書籍で学ぶ派なので、とりあえず一冊買いました。
わかりやすく説明されているのでオススメです。
少し古い本なので、情報が古かったりしたら都度ググりました。
あと、索引が少なめなのがちと痛い。。。

ドットインストールは主に書籍の補助で使いました。

Expressの知識

今回はExpressではなくrestifyを使っているのですが、Expressは情報が多くAPIサーバ開発のイロハを覚えられました。
上記書籍にExpressの解説もあります。


こちらも書籍の補助で使いました。


ドットインストールの説明がExpress 3.xなので、4.xでやる場合のやり方を参照しました。アリシャス!

restifyの知識

restifyは正確なREST Webサービスを構築に特化したNode.jsのモジュールで、
Expressとはちがいtemplateやレンダリングな機能はない代わりに「厳格な」APIサービスを構築できるようになっているとのこと。でもExpress勉強すればだいたい似た要領なのでわかるはず。

API Guide | restify
公式のドキュメントです。超英語。

mongoDBの知識


ちなみに書籍は買ってません。
概要をドットインストールで学んだ程度です。

mongooseの知識

mongooseはNode.jsを使ってmongoDBにアクセスするためのライブラリです。
わりとググれば情報がでてきます。

Mongoose SchemaTypes v3.8.24
公式ドキュメント。こちらも超英語。
こちらもわかんない時に参照する程度です。

勉強の進め方

  1. 書籍で概要理解+サンプルコードひたすら書いて動くものを作る
  2. ドットインストールで補習授業+動くものを作る
  3. やりたいことをとりあえずやってみる。
  4. つまづいたらググったり公式ドキュメント読んだり書籍開いたり
  5. 手順3,4の繰り返し

まとめ

いつもの勉強法晒しただけですね...