【Swarm】ステッカーのアップグレードを効率よく行うための方法
こんにちは。koogawaです。最近また無職になりました😇
今日はひさびさのSwarmネタです。
◆
皆さんはチェックインする際にステッカーを使ってますでしょうか?
ステッカーを使うことで、今の自分の気持ちを表したり、食事中や仕事中などのステータスを知らせることができます。
また、ステッカーにはレベルがあり、2X〜3X にアップグレードさせることができます。例えば 2X ステッカーを使うとチェックイン時に獲得できるコイン数を2倍に増やすことができます。
今回はこのアップグレードを効率よく行うための方法を紹介します。
※コインの使い道については次の記事でとても丁寧に解説されています。
ステッカーのアップグレードを効率よく行うための方法
例えばこの「Dark & Swarmy」ステッカーを 3X にアップグレードするためには、3件の新しいカクテルバーにチェックインする必要があります。
しかし、「カクテルバー」がどこにあるのかすぐにはわかりませんね。残念ながらSwarmの検索機能にもカテゴリで絞り込む機能はありません。
そこで活躍するのが拙作「Venue Map」です。
Venue Mapは、世界中に存在するベニューを地図上に表示することができるアプリです。
まずはアプリを起動して、右下の設定ボタンをタップします。
「By Category」から表示するカテゴリを絞り込むことができます。
「夜の娯楽スポット」 → 「バー」 → 「カクテルバー」の順にドリルダウンしていきます。
そして、設定画面を閉じるとカクテルバーのベニューだけが表示されます。
残念ながら私の大好きな練馬にはカクテルバーが1件しかないようです😫
そこで、渋谷に移動してみましょう。
さすがは渋谷。カクテルバーだけでこれだけのベニューが見つかりました!
◆
こんな具合に、ステッカーのアップグレードに必要なカテゴリに属するベニューを効率よく見つけることができます。
良ければ活用してみてください😃
iOSアプリ内のCookie情報を覗けるライブラリをつくった👀(デバッグ用)
iOSアプリのデバッグ中にCookieの中身が見たくなったので作りました。
機能
インストール
CocoaPods でインストールできます。
pod 'CookieManager' pod install
使い方
CookieManager
をインポートします。
import CookieManager
UINavigationController
の rootViewController として表示する例です。
let viewController = CookiesViewController() let naviController = UINavigationController(rootViewController: viewController) self.present(naviController, animated: true, completion: nil)
これだけです。
参考リンク
Stackoverflowの質問と回答を自由に編集できる権限をもらった
以前、こんな記事を書きました。
その後も地道に活動を続けた結果、ようやく 2,000 reputation に到達しました🎉
そこで今回は、この reputation level に到達するとどんな事ができるようになるのか書いていきたいと思います。
質問と回答を編集できるようになる
このレベルに達すると、Edit Questions And Answers 権限が付与され、自分以外の質問と回答を「いつでも」「自由に」編集することができるようになります。
この権限がなくとも「編集の提案」を出す事はできたのですが、reputation の高いユーザに承認してもらうまで反映されませんでした。しかし、この権限が付与されたなら、もう承認を待つ必要はありません。edit リンクから編集画面を開き、編集ボタンを押すだけで即時反映されます。
どんなときに投稿を編集するのか?
公式ドキュメントには次のような記載があります。
- to fix grammatical or spelling mistakes
- to clarify the meaning of a post without changing it
- to correct minor mistakes or add addendums / updates as the post ages
- to add related resources or hyperlinks
つまり、
- 文法またはスペルミスを直すべきとき
- 投稿の内容をより明確化したいとき (ただし投稿の趣旨は変えないように)
- 細かいミスの修正や時間のたった投稿に補足や更新を追加したいとき
- 関連する情報またはハイパーリンクを追加したいとき
に投稿を編集すべきです。
また、
Tiny, trivial edits are discouraged
とあるように、細かい些末な編集(例えば1文字直すだけ等)は推奨されません。
編集の提案も承認できるようになる
先ほどもちょっと触れましたが、このreputation levelに達していなくとも編集の提案を出す事はできました。2,000 reputationを超えると、これらの提案を承認する事ができるようになります。
最近は #stackoverflow の Suggested Edits (英文法等がおかしい質問を、権限を持ったユーザーが修正してくれるやつ)をレビューしてるんだけど、普通に英語の勉強になる
— Og🌗エンジニア🏝宮崎 (@koogawa) 2017年3月6日
Twitterにもつぶやきましたが、ネイティブによって修正された英語の内容は、見ているだけで勉強になります。
また、たくさんレビューすることによって獲得できるバッジも存在するので、積極的にレビューしていきたいと思います💪
※ただし、1日にレビューできる数には制限があるようです。
さらに上の権限
2,000 reputation の上にもまだまだ権限が存在します。
私のStackoverflow活動はこれからも続きます…
確定申告会場の混雑状況をなんとなく可視化するサービスを作った
確定申告会場の混み具合を可視化したい
— Og🌗エンジニア🏝宮崎 (@koogawa) 2017年2月19日
というわけで作りました。
確定申告会場の混み具合をなんとなく可視化するサイト: http://koogawa.github.io/kakutei/
「サービス」って書きましたが、Twitterの検索結果を並べただけです。
なお、すべての税務署は網羅できていません。リクエストがあれば追加します💪
つくりかた
材料
手順
Twitterの検索窓から検索します。
https://twitter.com/search?f=tweets&q=確定申告&src=typd
そしたら、検索結果画面の「︙」から「この検索をサイトに埋め込む」をクリックします。
レイアウトなどを設定して「ウィジェットを作成」をクリックします。
ソースコードが吐き出されるので、それを自分のHTMLに貼り付けます。これを必要な分だけ繰り返します。
最後にHTMLをサーバーにアップして完成です🎉
所感
ツイートを見ていると、今年から記載が義務付けられたマイナンバー絡みの混乱が目につきました。これから提出する人はマイナンバーカードを忘れずに持参しましょう。マイナンバーカードを持っていない人は必要な書類を準備しましょう。
Swift で Foursquare の API を使う(Swift 3編)
過去に書いた「Swift で Foursquare の API を使う - koogawa blog」を Swift 3 でも動くように書き直しました。
今月からSwiftの勉強を始めているkoogawaです。
勉強も兼ねて、Foursquare の API Client を Swift で作ってみました。
動作環境
- Xcode 8.2
- Swift 3.0
- FoursquareAPIClient 3.0.0
- CocoaPods 1.2.0
使い方
インストール
CocoaPods からインストールできるようにしました。
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! target 'HogeApp' do pod 'FoursquareAPIClient' end
セットアップ
ソースコード上で FoursquareAPIClient
をインポートします。
import FoursquareAPIClient
アクセストークン or クライアントID+クライアントシークレットで初期化します。
let client = FoursquareAPIClient(accessToken: “YOUR_ACCESS_TOKEN”)
or
let client = FoursquareAPIClient(clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET")
APIバージョンを指定することもできます。
// Set v=YYYYMMDD param let client = FoursquareAPIClient(accessToken: “YOUR_ACCESS_TOKEN”, version: "20140723")
ベニュー検索
さっそくベニューを検索してみましょう。
必要なパラメータを Dictionary
にセットします。
let parameter: [String: String] = [ "ll": "35.702069,139.7753269", // 緯度経度 "limit": "10", // 一度に取得する件数 ];
先ほど初期化した FoursquareAPIClient
の request(path:method:parameter:)
メソッドを実行します。引数にはAPIのパスとパラメータをセットします。method 引数を省略することで .get
になります。
client.request(path: "venues/search", parameter: parameter) { result in switch result { case .success(let data): // 成功 print(NSString(data:data, encoding:String.Encoding.utf8.rawValue)!) case .failure(.connectionError(let error)): // 通信エラー print(error) case .failure(.apiError(let error)): // 通信はできたけどAPIエラー print(error.errorType) // e.g. endpoint_error print(error.errorDetail) // e.g. The requested path does not exist. } }
レスポンスは Result<T, Error>
型で返ってきます。
public enum Result<T, Error> { case success(T) case failure(Error) init(value: T) { self = .success(value) } init(error: Error) { self = .failure(error) } }
エラー時には連想値として error
が返ってくるので、簡単なエラーハンドリングができるようになっています。
チェックイン
ベニューにチェックインすることもできます。
チェックインに必要なパラメータをセットします。
let parameter: [String: String] = [ "venueId": "55b731a9498eecdfb3854a9”, // Venue ID "ll": "37.33262674912818,-122.030451055438", // 現在地 "alt": "10”, // 標高 ];
同じように request(path:method:parameter:)
メソッドを実行します。今回はチェックインAPIの仕様に従い、method に .post
を指定しています。
client.request(path: "checkins/add", method: .post, parameter: parameter) { result in switch result { case let .success(data): // チェックイン成功 case let .failure(error): // チェックイン失敗 } }
他のAPIも path を書き換えることでリクエストすることができます。
デモ
近隣のベニューを検索するデモアプリを添付しております。
https://github.com/koogawa/FoursquareAPIClient/tree/master/Example
ベニューをタップすることでチェックインもできますよ。
デモアプリのアーキテクチャ
手書きですいませんw
Venue
オブジェクトはベニューデータを抽象化したデータモデルです。
FoursquareAPIClient
は、Foursquare API とのネットワーク通信を抽象化します。リクエストを送信して、レスポンスを Data にして返すところまでの責任を負います。
FoursquareManager
は、Venue
オブジェクトを管理するシングルトンオブジェクトです。ベニューリストをコントローラから取得するときはこれを介して操作します。予め accessToken
プロパティにアクセストークンを設定しておく必要があります(ここは微妙かも)。
実質的に、FoursquareManager
だけが FoursquareAPIClient
を操作することになります。
ここはこうしたほうが良い、などあればツッコミよろしくお願いします。
リンク
RealmSwiftで簡単なGPSロガー作ってみたのでメモ(Swift 3編)
以前書いた下記記事のソースコードが古くなっていたので、Swift 3対応版として書き直しました。
RealmSwiftで簡単なGPSロガー作ってみたのでメモ - koogawa blog
以前から気になっていた Realm
ですが、先日受講した id:KishikawaKatsumi さんの授業をきっかけに、実際に触ってみたくなりました。
Realm を理解するには何か作ってみるのが一番ってことで、簡単なGPSロガーを作ってみました。
次のような機能があります。
- Startボタンを押すと位置情報を記録開始
- アプリをバックグラウンドに落としても記録し続ける
- 位置情報が取得されると地図にもピンが立つ
- 1日経過したデータは起動時に自動削除
- Stopボタンを押すと位置情報の取得終了
***
以下、実装メモです。
動作環境
- Xcode 8.3
- Swift 3.0
- RealmSwift 2.4.2
- CocoaPods 1.2.0
RealmSwift インストール
次のような Podfile を用意して pod install
します。
use_frameworks! target 'GPSLogger' do pod 'RealmSwift' end post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['SWIFT_VERSION'] = '3.0' end end end
RealmSwift インポート
import RealmSwift
モデルクラス作成
位置情報を格納するためのモデルクラスを作ります。緯度、経度、作成日時のみを保持するようにしました。
class Location: Object { @objc dynamic var latitude: Double = 0.0 @objc dynamic var longitude: Double = 0.0 @objc dynamic var createdAt = Date(timeIntervalSince1970: 1) }
Realm では次の型が使用できます:Bool, Int8, Int16, Int32, Int64, Double, Float, String, NSDate, NSData
https://realm.io/docs/swift/latest/#supported-types
Startボタンを押したときの処理
位置情報の取得を開始します。
self.locationManager.startUpdatingLocation()
位置情報を永続化
取得できた位置情報(CLLocation
)から Location
モデルを生成し、Realmに永続化できるようにします。
let location = makeLocation(rawLocation: rowLocation) // Get the default Realm let realm = try! Realm() // Add to the Realm inside a transaction try! realm.write { realm.add(location) }
テーブルビューを更新
addNotificationBlock
メソッドでブロックを登録すると、Realmオブジェクトが更新されたときに通知を受けることができます。
self.token = realm.observe { [weak self] notification, realm in self?.tableView.reloadData() }
ここでは通知を受け取るたび(つまり位置情報が追加されるたび)にテーブルビューを更新しています。
Stopボタンを押したときの処理
位置情報の取得を停止します。
self.locationManager.stopUpdatingLocation()
通知の停止
先ほど addNotificationBlock
メソッドでブロックを登録した際に保持した NotificationToken
オブジェクトの stop
メソッドを呼ぶことで、通知の受け取りを停止します。
if let token = self.token { token.invalidate() }
アプリを起動したときの処理
すでに永続化されている位置情報をロードします。
// Get the default Realm let realm = try! Realm() // Load recent location objects return realm.objects(Location.self).sorted(byKeyPath: "createdAt", ascending: false)
createdAt
でソートをかけています。
古いデータの削除
古いデータがいつまでも残ってしまうのを防ぐため、1日経過した位置情報ログを削除します。
DispatchQueue.global().async { // Get the default Realm let realm = try! Realm() // Old Locations stored in Realm let oldLocations = realm.objects(Location.self).filter(NSPredicate(format:"createdAt < %@", NSDate().addingTimeInterval(-86400))) // Delete an object with a transaction try! realm.write { realm.delete(oldLocations) } }
データ量によっては時間がかかるので、バックグラウンドで実行するようにしています。
所感
CoreData を初めて使った時と比べると、かなりスムーズに導入・実装ができました。ドキュメントが充実しているのも安心ですね。
ソースコード
こちらに全てアップしてあります。Realm を使い慣れている方にとってはツッコミどころ満載だと思いますので、ご指摘など歓迎です:-)
リンク
React Native さわってみたメモ
今年のはじめにこんな記事がバズった。
批判的なコメントが多かったせいか、記事自体はもう消されてしまっている。
自分も数年前に Titanium を使ったことがあり、そんときは「Nativeで頑張ったほうが良さそう」と思って使うのをやめてしまった。ただ、その頃から状況も変わっているだろうし、この人の言っていることを無下に批判する気にはなれなかった。
そんなわけで、実際に自分の手で動かしてみることにした。以下はその時の作業メモ(自分用なので読みやすさは考慮してません)
動作環境
- react-native: 0.41.1
- Xcode 8.3
- Android Studio 2.2.3
作ったソースコード
https://github.com/koogawa/ReactNativeSample
インストール
Introduction · React Native に従って、Node、Watchman、React Native CLI をインストール。
brew install node brew install watchman npm install -g react-native-cli
サンプルプロジェクトの作成
iOS
react-native init AwesomeProject cd AwesomeProject
これだけで最低限の機能を備えたiOSアプリを生成してくれる。(言語はObjective-C)
react-native run-ios
を実行すれば iOS Simulator を起動してくれる。もしくは出力された xcodeproj を Xcode で開いて自分でビルドすることもできる。
ビルド自体は本当に簡単にできた。
cmd+d でデバッグメニューが出てくる。
出力されたコードを見てみる
デバッグメニューを出すのをどうやって実現しているのか気になったのでソースを追ってみると
RCTKeyCommands *commands = [RCTKeyCommands sharedInstance]; // Toggle debug menu [commands registerKeyCommandWithInput:@"d" modifierFlags:UIKeyModifierCommand action:^(__unused UIKeyCommand *command) { [weakSelf toggle]; }];
こんな感じでやっていた。cmdキーを検知できるの知らなかった。
AppDelegate も読んでみる。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSURL *jsCodeLocation; jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"ReactNativeSample" initialProperties:nil launchOptions:launchOptions]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; return YES; }
index.ios.js から RCTRootView
を生成して self.window.rootViewController にセットしてる感じなのね。
ためしに index.ios.js に変更を加えて再度ビルドしてみたけど、AppDelegate に差分は出なかった。某クラスプラットフォームのように、単純に機械的なコードを吐き出してるわけでは無さそうだ。この辺はとてもシンプル。
Android
SDK Manager を起動して、必要なパッケージをインストール。
- Google APIs
- Intel x86 Atom System Image
- Intel x86 Atom_64 System Image
- Google APIs Intel x86 Atom_64 System Image
このとき Android SDK Build-Tools 23.0.1
にチェックが入ってないとダメ。
環境変数 ANDROID_HOME
にもパスをセットする必要がある。
export ANDROID_HOME=${HOME}/Library/Android/sdk export PATH=${PATH}:${ANDROID_HOME}/tools export PATH=${PATH}:${ANDROID_HOME}/platform-tools
最初、ここのパスを間違えて結構ハマった。
次に Android Studio から AVD Manager を起動して、エミュレータを起動しておくのがポイント。
AVD Managerは
android avd
のコマンドでも起動できる。
react-native run-android
でアプリを実行。
こんな感じで Android アプリもビルドできた。
タブバーを表示してみる
TabBarIOSの公式ドキュメント通り実装してみるが、何故かエラーが出る。。🤔
調べてみてわかったのだが、
var React = require('react'); var ReactNative = require('react-native');
みたいな書き方はすでに古くなっているらしい😩
Does React Native use require or import? - Stack Overflow
import React, { Component } from 'react'; import { AppRegistry, TabBarIOS, StyleSheet, Text, View } from 'react-native';
のような書き方に修正することで、なんとかビルドが通った。
見てるドキュメントが間違ってるのかもしれないけど、公式ドキュメントが最新になってないのはちょっと焦った😞
TabBarIOS
という名前なので、Androidの場合はどうするんだろう?という疑問が湧いたが、やはり同じことを考える人がすでにいた。
How to make Tab bar for Android like TabBarIOS in react native? - Stack Overflow
こうやってiOS用のコードとAndroid用のコードを別々に管理していくことになりそう。
所感
- ホントに簡単にアプリを作り始められる
- 公式ドキュメント通りやっても動かないことが多々ある
- 正しい情報を探すことになり、ここに多くの時間を割くことになりそう
- ビルドしてみないとエラーかどうかわからないのがつらい
- コードの補完機能がないのが地味につらい
- パフォーマンスとかはもうちょっと使ってみないとわからない
- iOS/Android のバージョンが上がったときに追従してくれるか不安
iOSアプリはXcode で、AndroidアプリはAndroid Studioで作りたいと思った。何を言っているのかわからねーと思うが(略
— Og🌗エンジニア🏝宮崎 (@koogawa) 2017年2月4日