本文へスキップ
Hironobu Iga

GDPR 対象国の判定を iOS アプリ側で行う方法を考える

EEA 加盟国にいるかどうかをアプリ内でどう判定するのが妥当か、いくつかの選択肢を比べた考察です。

公開日

この記事は別サイトにも掲載しています。 https://qiita.com/iganin/items/11318a0f021e0204e41f

はじめに

背景

2018 年 5 月 25 日より個人情報保護に関わる規則として、EEA 加盟国を対象に GDPR - EU 一般データ保護規則が施行されました。各種のアプリからのお知らせ等でご存知の方も多いかと思います。(プライバシーポリシーの改定などで直近多くの連絡が行われていました) 本保護規則の施行に際しまして、サーバ側、DB 側など各レイヤーで対応が必要かと思われますが、本記事では iOS アプリ内で保護対象国に現在いるかどうかの判定をいかに行うのが良いかを考察してみます。

前提

  • 本記事の見解は筆者の個人的なものであり、筆者の所属する組織の公式見解は一切含みません
  • 筆者は法律は専門としていないため、法的解釈に関して誤りを含む可能性があります

法的な解釈や具体的な対応内容に関しては以下の参考資料を当たるのが良いかと思われます。

使用環境

以下の環境を使用しています。

  • Xcode 9.3
  • Firebase iOS SDK 4.9.0
  • Firebase RemoteConfig

達成目標

以下を本記事での達成目標とします。

  • GDPR 対象国の判定をアプリ内で行う

具体的には以下の対応になります。 GDPR 対象国(EEA 加盟国 31 ヶ国)にアプリ使用時に滞在しているかどうかを判定する。「アプリ使用時に」としているのは GDPR の規則内に以下の記載があるためです。

GDPR の対象となる個人データは、EU 加盟国など 31 か国の欧州経済領域(EEA)域内に存在する個人に関する個人データです(GDPR 第 2 条)。国籍や居住地を問わず、EEA 域内に短期滞在する出張者や旅行者の情報も対象となります。

そのため、日本国籍を所持しているユーザーであったとしても、EEA 加盟国に旅行に行った場合は、旅行期間中の情報は GDPR の対象となり得ます。

方法 1 TimeZone の使用

アプリの TimeZone を使用して判定する方法です。iOS の設定アプリ内で固有の国にしておらず、自動設定となっていた場合は、現在地から適切な TimeZone が取得できるため、タイムラグなく、判定することができます。問題点としては、TimeZone をユーザーが固定していた場合に現在地の情報が正常に反映されないことです。

iOS の「日付と時刻」設定。自動設定がオンで、時間帯が東京になっている

現在の TimeZone は下記の方法で取得できます。

let currentTimeZone = TimeZone.current.identifier

対象国が今後追加・削減されることを考慮し、対象国のリストはアプリ内部でのみ持つのではなく、外部から追加・削除できるようにするのが良いのではないかと思われます。例えば、Firebase の RemoteConfig で対象国の TimeZone のリストを作成し、アプリで配列化、現在の TimeZone が該当の TimeZone に含まれるかで判別するというのが良いのではないでしょうか。 例えば、以下のようなメソッドを作成すれば判定できそうです。

// RemoteConfig から対象国の TimeZone の String を取得し、配列化します
// 例えば、該当国の TimeZone を ',' 区切りで設定していた場合
// なお RemoteConfig からの値取得処理は割愛します、参考文献をご参照ください
let targetCountryTineZones = targetCountryTineZonesString.components(separatedBy: ",")

if isGDPRTargetCountry(targetCountryTimeZones: targetCountryTineZones) {
    // GDPR 対象国用の処理
}

func isGDPRTargetCountry(targetCountryTimeZones: [String]) -> Bool {
    let currentTimeZone = TimeZone.current.identifier
    return targetCountryTimeZones.contains(currentTimeZone)
}

なお、補足ですが、iOS で規定されている TimeZone の一覧は以下のメソッドで取得可能です。

TimeZone.knownTimeZoneIdentifiers

方法 2 GeoCoder の使用

アプリで緯度・経度を取得している場合に使用できる方法です。 緯度・経度が取得できている場合は、iOS の CLGeocoder を使用して以下のように国コードが取得可能です。 ※ サンプルで取得しているコードは 2 桁の国コードです。(例:日本 - JP) しかし、国コードの取得が非同期であることから、取得タイミングや方法は検討が必要です。 例えばですが、アプリ起動時などに国コードを取得、UserDefaults に保存、判定時には UserDefaults の保存情報を使用、という方法が良いのではないでしょうか。

final class GeoCoderWrapper {
    static private var countryCode: String? {
        get { return UserDefaults.standard.string(forKey: #function) }
        set { UserDefaults.standard.set(newValue, forKey: #function) }
    }

    // 緯度・経度情報から Country コードを取得し、UserDefaults に保存
    // location は CLLocationManager で取得済みとする
    static func updateCountryCode(location: CLLocation) {
        let geoCoder = CLGeocoder()
        geoCoder.reverseGeocodeLocation(location) { (placeMarks, error) in
            // placeMark は複数返却されるため、1 番目を取得
            GeoCoderWrapper.lastISOCountryCode = placeMarks?.first?.isoCountryCode
        }
    }
}

先ほどの TimeZone の場合と同じく、Firebase やサーバ側で対象国のリストを生成しておき、該当の国コードが対象国に含まれるかどうかを持って、判定を行います。

func isGDPRTargetCountry(targetCountryCodes: [String]) -> Bool {
    guard let currentCountryCode = GeoCoderWrapper.countryCode else { return true }
    return targetCountryCodes.contains(currentCountryCode)
}

なお、対象国 31 ヶ国の国コードのリストは下記になりそうです。

LI,IS,NO,AT,BE,BG,HR,CY,CZ,DK,EE,FI,FR,DE,GR,HU,IE,IT,LV,LT,LU,MT,NL,PL,PT,RO,SK,SI,ES,SE,GB

番外編

Firebase の条件(地域、言語)

Firebase の RemoteConfig を設定する際に該当のプロパティに対し、条件を設定し条件毎に返却値を分けることができます。ただ、Firebase の該当プロパティは設定アプリの地域や言語を見て判定を行っていました。地域や言語設定はユーザーが明示的に変更しない限り変更されません。そのため、日本から EU 圏に移動していたとしても、地域・言語は変更されないため、GDPR の対応の対象としては認識できず、要件を満たすことができません。 Firebase のコンソール上で直感的に対象を絞り込めるため、良いなと考えていましたが、この方法は使用できなさそうです。

iOS の「言語と地域」設定。地域が日本になっている

Firebase RemoteConfig の条件編集画面。国 / 地域で EEA 加盟国を選んでいる

最後に

GDPR は罰則が年間売上の 4% か 2000 万ユーロのいずれか高い方と大変厳しく、ユーロ圏を対象にサービスを提供しているアプリでは対応が必須だと考えています。本情報がどなたかのお役に立てましたら幸いです。こういった方法があるのではないか、といった情報がありましたら、コメントいただけますと幸いです。

参考資料

iOS

iPhone

国コード

GDPR