Goalist Developers Blog

iOS11になって変わったAppStoreまとめ

こんちは。渡部です。

f:id:watabe1028:20171222193758j:plain

この季節の「気づいたら指先が切れてた」現象をなんとかしたいです。はい。

今回はiOS11になって変わったことAppStore編を思いつく限り書いていきます。
ご参考までに。
 
 

1.アイコン

 アイコンが変わってます。
 筆者は訳あってiOS10を保ってます。
 (画像サイズが違うのは勘弁)

 iOS10
f:id:watabe1028:20171222194229p:plain
 
 iOS11
f:id:watabe1028:20171222194241j:plain
 
 

2.トップセールスランキングが削除

 インストール基準の一つがなくなるのは
 ゲーム系開発会社にはかなりの痛手かと。
 なのでこれからは流入経路は広告か
 検索からのインストールに偏っていきそうです。
 
 iOS10
f:id:watabe1028:20171227103502j:plain
 
 iOS11
f:id:watabe1028:20171227103518j:plain

 
 

3.タブが「Today」「ゲーム」「App」に

 2ともかぶるんですが「見つけやすい」ようにリニューアルされてると思います。
 ランキングは勝手に入ってくる情報ですが
 検索は目的のアプリを探す行為です。
 なので見つけやすさ、ファーストオンボーディングが重要になってくるかと。
 
f:id:watabe1028:20171227103049j:plain

 
 

4.ストアのアプリ一覧で横画面が可能に、スクショの枚数は3枚に

 今までは検索後の一覧画面では2枚のスクショが表示されてましたが
 iOS11からは3枚表示されます。
 また1枚の横画像の設定も可能になりました。
 
 iOS10
f:id:watabe1028:20171227103157p:plain
 
 iOS11
f:id:watabe1028:20171227103219p:plain

 
 

5.コメントへの返信機能

 レビューに対して返信できるようになりました。
 CXという言葉が流行り始めているように
 これからはアプリもカスタマーへのサポートが大事になっていきます。
 また、レビューをリセットすることもできます。
 ASO的にはレビューの件数や星の数が非常に大事になってくるので
 レビューリセットは考えものですね。

 
 

所感

重複しますがストアが全体的に「見つけやすく」なるようにリニューアルされた気がします。
またレビューの返信機能など、アプリをサービス化し、サポートもしっかりやれよ!的な
メッセージのようなものも感じます。
改善が停止されてるアプリが溢れてますからね。。。
 
アプリのインストール基準でもあるレビュー件数と星の数がさらに重要度が増した気がします。
ランキングよりも評価やサポートがユーザーのインストール基準になっていく傾向でしょうか。
 
アプリの露出からサポートまで、UXの定義がまた広くなりそうです。
 
 

Selenium2を3に上げてみる

こんにちは ゴーリスト開発のモリツグです

そろそろSelenium2から危険な香りがするので、3に上げることしました。
ChromeのヘッドレスがEC2を利用してクローリングする時にすごい便利ですね。
今回はJavaでSelenium3 WebDriverを動かしてみたいと思います。

手順

公式サイトのダウンロードからJavaのライブラリをダウンロードする
・EclipseやInteliJなど好みのIDEでライブラリ参照するように設定する
ドライバダウンロードページから環境にあったchromeドライバを落としてくる
・ソースコードを書いて確かめる

今回落としてきたSeleniumのバージョンは3.8.1でした、知らない間に4になりそうな勢いです。
注意点としてはchromeブラウザのバージョンにドライバのバージョンが対応しているかどうかを確認することです。
「同じソースコードなのにある日突然動かなくなった!」という場合は、だいたいChromeが更新されてバージョンが上がったせいで、ドライバが対応できなくなったパターンが多いです。

Chromeは公式サイトからは最新版しか落とせないので、Chromeが最新になっちゃったけど、それに対応した最新のドライバが出ていない状況というのは起こりえます。
「今すぐに動かさないとやばい!古いバージョンのChromeが欲しい!」という場合は、以下のサイトから落とせます。古くした後は忘れずに自動更新はoffにしときましょう。

www.slimjet.com

では最後にver2と全く同じソースコードで動くのか確認します

public void exec() throws Throwable {
    System.setProperty("webdriver.chrome.driver", "path to your chrome driver");
    WebDriver driver = new ChromeDriver();
    // ヘッドレスの場合
//     ChromeOptions chromeOptions = new ChromeOptions();
//     chromeOptions.addArguments("--headless", "window-size=1280,1024"); // xvfbとか一切無しでdislayサイズも指定できちゃう
//     WebDriver driver =  ChromeDriver(chromeOptions);
    

    driver.navigate().to("https://www.google.co.jp/");

    WebElement input = driver.findElement(By.cssSelector("#lst-ib"));
    input.sendKeys("goalist");
    input.sendKeys(Keys.chord(Keys.ENTER));

    ExpectedCondition<List<WebElement>> waitFunc = new ExpectedCondition<List<WebElement>>() {
        public List<WebElement> apply(WebDriver driver) {
            List<WebElement> curTitleEle = driver.findElements(By.cssSelector("#search .rc .r a"));
            if (curTitleEle == null || curTitleEle.size() == 0) {
                return null; // NoSuchElementExceptionかreturn nullしてるあいだは続行
            }
            return curTitleEle;
        }
    };

    Wait<WebDriver> wait = new WebDriverWait(driver, 15);
    try {
        System.out.println("start wait");
        List<WebElement> result = wait.until(waitFunc);
        result.get(0).click();
        System.out.println("end wait");
    } catch (TimeoutException e) {
        e.printStackTrace();
        System.out.println("time out");
    }
}

まとめ

Chromeを使う限りではselenium2と全く同じソースで動くようです。
今すぐ3に上げましょう。

Angularで転職用ウェブアプリのフロント開発を開始!

f:id:TinkerJack:20171215191005p:plain皆さん、

お疲れ様です! コードで遊ぶのが好きなティンカーです! 最近コトリンの勉強をしつつ充実してる感もありますけども、やっぱりウェブでの開発もしたいと思って(現在本業)、Angularで簡単なアプリを作ってみようかと思います!

本日のグロサリー:

  • Angularとは。

  • 環境構築。

  • アプリ作成!

Angularとは

AngularはJavascriptにコンパイルされる言語でウェブアプリの開発をさせるフロントエンドフレイムワークです!

まずは環境設定から始めたいかと思っています!

環境構築

こちらのブログの前提はMac OS何ですが、Windowsの方は同僚の飯尾さんが作ってくれたWindows用の環境構築の記事を読んでください!

developers.goalist.co.jp

npmとnodejsが必要になるので、そこから始めます! ですが、先にHomebrewと言うMac OS専用のパッケージマネージャーを使ってインストールしますので、 まずは下記の用にhomebrewのインストールをしましょう!(詳しくは下記のリンクで)

qiita.com

次は下記のコマンドでNodeJSとNPMのインストールをしましょう!

f:id:TinkerJack:20171215163159p:plain

これでよし! 後はangular-cliのインストールをすれば、、、

f:id:TinkerJack:20171215163348p:plain

オーケー! これでAngularのアプリを生成するための環境設定は完了しました!

アプリ作成!

いよいよですね!

まずはAngularのアプリのgenerateをしましょう!

f:id:TinkerJack:20171215163613p:plain

下記の通り色んなディレクトリーが自動生成されます!

f:id:TinkerJack:20171215163808p:plain

"Project 'JobNetworker' successfully created." と言うメッセージが見れたら、プロジェクトが無事作成されたら合図と見なします!

次はサーバーを起動するコマンドを打ちます!

f:id:TinkerJack:20171215164246p:plain

よーし!次はようやく、localhost:4200に遷移すると、デフォページとしてAngularの正式のチュートリアルが反映されると無事アプリ作成ができました!!

f:id:TinkerJack:20171215165648p:plain

おめでとうございます!

次からここにある物を消し、ゼロから転職サイトアプリを作るので、楽しみです!!

次回の用意としては、お好きなIDEをインストールしてください!

現在使っているIDE / エディターに関しては、ウェブストームを使用して、開発しています。

www.jetbrains.com

ただし、データの使用もすると思うので、いずれかバックエンドの開発もするつもりです。 なのでIntelliJ IDEAの購入をお勧めしますが、お好きなテキストエディタやIDEでももちろんオーケーです!

www.jetbrains.com

本日の記事の内容は以上となります!

次回は本格的な転職サービスの開発を開始します!

来週までお元気で!

See you next week!

P.S: もしかたら、いやもしかしたらの話何ですけども、まさかのkotlinを使用したこのアプリのバックエンド開発も。。。?

次回のお楽しみにー

ゴーリストエンジニア
イムラーン

Angularで WARNING in Circular dependency detected だよ〜ドラえも〜〜ん

はい。
ゴーリスト開発の飯尾です。

タイトルの通りなんですけど
別に解決してないんですけど

Angular CLI を1.1.3から1.5.5にアップデートしたら
アラ〜〜〜

WARNING in Circular dependency detected:
src/app/services/auth.service.ts -> src/app/services/request.service.ts -> src/app/services/auth.service.ts

WARNING in Circular dependency detected:
src/app/services/request.service.ts -> src/app/services/auth.service.ts -> src/app/services/request.service.ts

とはいえ、コンパイル自体は通るしプロダクション用ビルドも普通にできる……

どうする???

github.com

「Angular CLI 1.3.0から起こる」
「showCircularDependenciesをfalseにして見えなくすればOK」

そんな……
うるせーから黙らせる的な発想でいいの……

いったん、循環参照になっちゃうメソッドを別サービスに出してそれぞれDIする

警告オフにして他の問題に気づかないとかちょっと避けたいので……

社内Angularの雄にきいてみる

f:id:y-iio:20171215182535p:plain

ウオ〜〜〜
そういう!ことなのか!!?

Angular5にアップデートしてHttpモジュールを変更するゾ

こんにちは🍣
ゴーリスト開発の飯尾です

Angular4.3以下から5にアップデートするとき
Httpクライアントモジュールは @angular/http が非推奨になったので
@angular/common/http を使うように変更しました

どんなかんじに書き換えたのかまとめてみました

Before

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Http, Headers, Response, RequestOptions } from '@angular/http';
import { MyResponse } from '../entity/my-response';

@Injectable()
export class RequestService {

  constructor(private http: Http) { }

  public post(params: string): Observable<any> {
    const headers: Headers = new Headers({
      'Content-Type': 'application/json',
      'dataType': 'json'
    });
    const options: RequestOptions = new RequestOptions({headers: headers});
    return this.http.post(REQUEST_URL, params, options)
      .map((res: Response) => {
        return new MyResponse(res.json());
      });
  }

}

After

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import { MyResponse } from '../entity/my-response';

@Injectable()
export class RequestService {

  constructor(private http: HttpClient) { }

  public post(params: string): Observable<any> {
    return this.http.post<MyResponse>(REQUEST_URL, params);
  }

}
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class MyInterceptor implements HttpInterceptor {

  constructor() { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const req = request.clone({
      setHeaders: {
        'Content-Type': 'application/json',
        'dataType': 'json'
      }
    });
    return next.handle(req);
  }
}

違いはなんなん

ヘッダーのオプション設定は今までのが使えなくなったので
HttpInterceptorに出して使うようにしてみました

レスポンスの型指定ができるようになったので嬉々として使ってます

ついでに

こんな記事もこの前書きましたの

developers.goalist.co.jp

初めまして、Pattamada Ponnapa Chinnapa です!

Hello World!

That's what every programmer says first, right?

あ、すみません、日本語のブログでしたね(言語制限がないと言われてますが、さすがに最初から全部英語などにしたら、みんな逃げちゃいますね)。

タイトルはそうなんですが、チナパと申します、新しくゴーリストの開発部に入った者です!

f:id:c-pattamada:20171207152452j:plain

^- 私

今回、軽く自己紹介させていただきます! 母国はインドです!ただし、日本には現在五年目です! さて、次の質問はいつもカレーについてなので、納得します、インド人らしくカレーがすきです、 日本のカレーもその範囲の中に来ます、もちろん

プログラミングに関して、詳しい知識はまだないんですが

  • Java Javascript PHP Python

  • はみんな少しできます。AIにもとても興味があります!

ここまで読んでくれた皆さんに、もし機械学習に興味があればここででも第一歩踏めます!

MNIST For ML Beginners  |  TensorFlow

グーグル翻訳が気に入らない人のために、これからのポストはこの話題にしようと思ってますので、楽しみにしてください!

どうせ誰も見ないけどSwiftのガイドライン的なものを少しずつ作る

こんちは。渡部です。

f:id:watabe1028:20171129095304p:plain

確かゴーリストでは昨年あたりにようやくJavaのコーディング規約を作りました。
一体どれほどの社員が見たでしょうか?
CTOは規約を守っているのでしょうか?
三項演算子にスペースは入れてくれているのでしょうか?
 
社内にSwiftユーザ少ないけどこれからきっと増えるから
ガイドラインを作っとこ、と思ったので少しずつブログで作っていきます。

 

命名規約

クラス名、構造体名、列挙型名、プロトコル名

基本キャメル型ですよね。
宗教論争になりますがここではキャメル型で通します。

class GoalistModel {}

protocol GoalistModelDelegate: class {}

enum Week: String {}

struct Author {}

 
 

グローバル定数名、クラス定数名

こちらは大文字のスネーク型を使います。
完全に好みだけど世の中的にこれが多い気がします。
でふぁくとすたんだーど。

public let GOALIST_VALUE_NAME = "hokoriwomotsu"

class GoalistModel {
   static let TABLE_NAME = "GOALIST_TABLE"
}

 
 

変数名、関数名

もちろんキャメル型。

var userName: String = "watabe"

func sendMessage(textMessage: String) -> Void {

}

 
 

定義方法

変数、定数

1行で複数の宣言はやめましょう。
基本醜い、見にくいです。

let userName: String = "watabe"
let userId: Int = 0

letとvarの違いは
letは定数、varは可変と認識してます。
間違ってたらすんません。

 

型宣言

基本します。
明確な場合はしなくても良くね?
と言われますがダメです。(圧)

let text = "hello"         // は?
let text: String = "hello" // OK

let text = data["text"] as String         // は?
let text: String = data["text"] as String // OK

 
 

配列の初期化

色々あって何がよいやら、ですが以下の記述方法にします。
完全に好みです。

let member = ["watabe", "moritsugu", "iio", "chinapa"]           // は?
let member: [String] = ["watabe", "moritsugu", "iio", "chinapa"] // OK

 
 

今回は終わり

いやーガイドライン作成って大変ですね。
今日は面倒になってきたからこの辺にしておこう。そうしよう。

次は構文とか決めていきます。