Help us understand the problem. What is going on with this article?

位置情報を使ったブラック企業通知アプリをリリースした【個人開発】

ブラック企業を地図にマッピングし、周辺にブラック企業があればプッシュ通知で知らせてくれるアプリをリリースしました!

個人でwebサービスやアプリを開発している人に少しでも何かタメになることがあればと思いサービスを作ろうと思った経緯や使用技術などをずらずらと書いていこうと思います!

リリースしたサービス

iOS
ブラックアラート - 周辺ブラック企業プッシュ通知アプリ

Android
ブラックアラート - 周辺ブラック企業プッシュ通知アプリ

どんなアプリ?

位置情報を利用して周辺にブラック企業があればプッシュ通知で知らせてくれるアプリです。

できること

周辺にブラック企業があればプッシュ通知

notify.PNG

ブラック企業の検索

IMG_1635.PNG

IMG_1635.PNG

ブラック企業の詳細閲覧、ツイート

IMG_965BC3B1EAA9-1.jpeg

開発経緯

去年、ブラック企業をマッピングした某webサービス様が話題になっていたのがきっかけで自分もiOSアプリで出したいと思いました。(わたしが開発者ではありません。)
ただ、ブラック企業をマッピングして表示するだけではオリジナリティにかけてしまうので周辺にブラック企業があれば通知するのはどうかというアイデアから生まれました。

ブラック企業の基準は?

厚生労働省が公表している「労働基準関係法令違反に係る公表事案」に掲載されている労働基準法等違反で書類送検された企業を指しています。

下記のサイトの「労働基準関係法令違反に係る公表事案」PDFファイルよりダウンロードできます。
長時間労働削減に向けた取組

私の独断偏見で追加はしておりません

技術周り

以下は技術周りについてです

使用技術, 環境

  • Swift4
  • Realm
  • Ruby2.5
  • Ruby on Rails 5.2
  • GoogleCloudPlatform
    • Maps SDK for iOS
    • Places API
  • Gitlab
  • Amazon s3
  • Firebase Analytics

PDFのデータをcsvに変換

当アプリはAmazon s3にブラック企業一覧csvを配置し、ダウンロードしてRealmに保存しています。

対象PDF(労働基準関係法令違反に係る公表事案)をExcelに変換します。
smallpdfというサイトでPDFからExcelに変換しました。(他に何か良い方法あれば教えてください・・・!)

変換したExcelをRuby, Railsでcsvに書き出します。

  • Excelを扱うGem

スクリーンショット 2019-01-14 3.12.03.png

Excel化した各項目をcsvとして書き出します。

所在地から緯度経度を取得

Maps SDK for iOS にて地図にピンを配置するには、緯度経度の情報が必要です。
そのため、Places API を使いました。

こんな感じで簡単に緯度経度を取得できます。

result = @client.spots_by_query('東京都港区...')

完成CSV

最終的に下記のようなcsvとしAmazonS3にアップロードします。

id name address longitude latitude public_date detail etc
1 hogeカンパニー 東京都港区... 142.357 43.2 H29.6.15 トラクター・ショベルの運転を無資格の労働者に行わせたもの H30.2.5送検
2 fugaコーポレーション 東京都豊島区.. 143.357 43.3 H29.6.17 フォークリフトに接触するおそれがある箇所に労働者を立ち入らせたもの H30.2.5送検
... ... ... ... ... ... ... ...

csvをダウンロードしRealmに保存

アプリ起動時の初回のみcsvをダウンロードし、csvの各カラムをRealmに保存し、ブラック企業を配置します。
※1日に1度だけcsvを再度ダウンロードし、増減チェックしてあれば更新するようにしています。

// ブラック企業モデル
import RealmSwift

class Company: Object {
    let id = RealmOptional<Int>()
    @objc dynamic var name: String? = nil
    @objc dynamic var address: String? = nil
    let longitude = RealmOptional<Double>()
    let latitude = RealmOptional<Double>()
    @objc dynamic var public_date: String? = nil
    @objc dynamic var law: String? = nil
    @objc dynamic var detail: String? = nil
    @objc dynamic var etc: String? = nil

    @objc dynamic var notification: CompanyNotification?
}
// 取り込み
let importBycompanies = List<Company>()

// csvをparseしてeach
for csvCompany in csvCompanyRows {
    let company = Company()
    company.id.value = id
    company.name = name
    company.address = address
    company.longitude.value = longitude
    company.latitude.value = latitude
    company.public_date = public_date
    company.law = law
    company.detail = detail
    company.etc = etc

    importBycompanies.append(company)
}

// 書き込み
let realm = try! Realm()
try! realm.write {
    for company in importBycompanies {
        realm.add(company)
    }
}

プッシュ通知条件

現在地が更新されたタイミングで一番近いブラック企業が一定の圏内にあれば通知しています。
また、何度も同じブラック企業の通知を防ぐために一度通知したブラック企業は24時間再通知をしません。

使用したGemやライブラリ

  • Swift
    • TwitterKit ブラック企業の詳細情報をツイート
    • SearchTextField ブラック企業検索でサジェストさせる
    • PopupDialog 自作のviewcontrollerをモーダルとして表示できる。(検索モーダルで使用)

追記:随時更新予定。
質問などここらへんもっと詳しく説明して欲しいなどあればお気軽にどうぞ!(長文書き慣れていないので端折ってた部分とかあるのでw)

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away