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

Call Directory Extension の部分だけ翻訳してみた

More than 3 years have passed since last update.

翻訳元
本家の記事

CallKit

Overview

The CallKit framework provides programmatic access to VoIP functionality, as well as call blocking and identification.

CallKitフレームワークは、VoIP機能にプログラムからアクセスしたり、着信拒否したり、識別したりします。

いきなりidentificationで、意味わからなかったのですが、読み進めていくと発信者を識別するために電話番号と発信者名のペアをあらかじめ登録する機構がCall Directory Extensionの機能として提供されているようです。call blocking も Call Directory Extensionの機能の一つで、着信拒否リストを登録する機能のようです。他にも機能があったのですが、Call Directory Extensionが気になったので、これ以外は別途書きます。 (と言って放置した記事が何個もある...

~ 中略 ~

Call Blocking & Identification

Apps can create a Call Directory Extension to identify and block incoming callers by their phone number.

アプリケーションは 電話番号を元にそれを拒否したり、誰からの着信であるかを特定するために、Call Directory Extension を使うことができます。

Identifying Incoming Callers

When a phone receives an incoming call, the system first consults the user’s contacts to find a matching phone number. If no match is found, the system then consults your app’s Call Directory extension to find a matching entry to identify the phone number. This is useful for applications that maintain a contact list for a user that’s separate from the system contacts, such as a social network, or for identifying incoming calls that may be initiated from within the app, such as for customer service support or a delivery notification.

電話で着信を受けた時、システムはまず初めに、ユーザーの連絡先を参照し、該当する電話番号がないか調べます。もし、一致するものがなければ、システムはあなたのアプリのCall Directory extensionからその電話番号にマッチするエントリーを調べます。これはアプリケーションがシステムの連絡先と別に連絡先を管理している時に有用です、例えば、SNSの連絡先やアプリ内で発信ID(idenfifying incoming calls)が初期化されている場合、配達やカスタマーサービスなど。

For example, consider a user who is friends with Jane in a social networking app, but doesn’t have her phone number in her contacts. The social networking app has a Call Directory Extension, which downloads and add the phone numbers of all of the user’s friends. Because of this, when the user gets an incoming call from Jane, the system displays something like “(App Name) Caller ID: Jane Appleseed” rather than “Unknown Caller”.

例えば、Jane - SNS上の友人 - しかし、彼女の電話番号が連絡先にない時があります。このSNSアプリはCall Directory Extensionを使って、SNS上の友人の電話番号を全てダウンロードして置いて、発信者識別情報(電話番号と、表示名のペア)追加しておくことによって、Janeからの着信が来た時に、ディスプレイ上に「不明な電話番号」ではなく「(アプリ名) Call ID: Jane Appleseed」と表示することができます。

To provide identifying information about incoming callers, you use the addIdentificationEntry(withNextSequentialPhoneNumber:label:) method in the implementation of beginRequest(with:).

発信者を識別する情報(表示名)を提供するには、addIdentificationEntry(withNextSequentialPhoneNumber:label:) を、beginRequest(with:)の実体でコールしてください。

class CustomCallDirectoryProvider: CXCallDirectoryProvider {
    override func beginRequest(with context: CXCallDirectoryExtensionContext) {
        let labelsKeyedByPhoneNumber: [CXCallDirectoryPhoneNumber: String] = [  ]
        for (phoneNumber, label) in labelsKeyedByPhoneNumber.sorted(by: <) {
            context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)        }
        context.completeRequest()
    }
}

Because this method is called only when the system launches the app extension and not for each individual call, you must specify call identification information all at once; you cannot, for example, make a request to a web service to find information about an incoming call.

このメソッドは個々の発信ではなく、システムがextension起動時に1回だけしかコールしないので、発信者の識別情報の付与は全てこの1回限りでおこなってください。例えば、Webサービスに対して情報の検索リクエストを出すようなことはできません。

(なるほど、だから、さっきのJaneの例で、わざわざダウンロードしたのか、でも、途中から友人増えることもあるし、発信者識別情報を追加したりしたくなったらどうするんだろう。)

サンプル作ってみました。1分。
ちなみに、上記のソースコード上のphoneNumber(CXCallDirectoryPhoneNumber)は、国コードから始まります。日本のケータイなら、

電話番号 CXCallDirectoryPhoneNumber
080-xxxx-yyyy 8180xxxxyyyy

こんな感じです。Call Directory Extensionをいつも通りターゲットから追加すると、サンプルコードが書かれているので、まぁ、あとはうまくやってください。なんかもう説明すらいらなそうくらいわかりやすいコードになってます。

class CallDirectoryHandler: CXCallDirectoryProvider {
    // このメソッドはapp extensionがlaunchした時にコールされるらしいので、
    // ここで、context.addIdentificationEntry をして、発信者識別の登録を済ませよ、とのこと。
    // ちなみに、着信拒否もここだそうです。context.addIdentificationEntry
    override func beginRequest(with context: CXCallDirectoryExtensionContext) {
        context.delegate = self

        do {
            try addBlockingPhoneNumbers(to: context)
        } catch {
            NSLog("Unable to add blocking phone numbers")
            let error = NSError(domain: "CallDirectoryHandler", code: 1, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }

        do {
            try addIdentificationPhoneNumbers(to: context)
        } catch {
            NSLog("Unable to add identification phone numbers")
            let error = NSError(domain: "CallDirectoryHandler", code: 2, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }

        context.completeRequest()
    }

    private func addBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) throws {
        // Retrieve phone numbers to block from data store. For optimal performance and memory usage when there are many phone numbers,
        // consider only loading a subset of numbers at a given time and using autorelease pool(s) to release objects allocated during each batch of numbers which are loaded.
        //
        // Numbers must be provided in numerically ascending order.
        let phoneNumbers: [CXCallDirectoryPhoneNumber] = [ 14085555555, 18005555555 ]

        for phoneNumber in phoneNumbers {
            context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
        }
    }

    private func addIdentificationPhoneNumbers(to context: CXCallDirectoryExtensionContext) throws {
        // Retrieve phone numbers to identify and their identification labels from data store. For optimal performance and memory usage when there are many phone numbers,
        // consider only loading a subset of numbers at a given time and using autorelease pool(s) to release objects allocated during each batch of numbers which are loaded.
        //
        // Numbers must be provided in numerically ascending order.
        let phoneNumbers: [CXCallDirectoryPhoneNumber] = [ 8180xxxxyyyy ] // 🍎 ここだけ書き換えただけ
        let labels = [ "あんず" ] // 🍎 ここだけ書き換えただけ

        for (phoneNumber, label) in zip(phoneNumbers, labels) {
            context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)
        }
    }

}

extension CallDirectoryHandler: CXCallDirectoryExtensionContextDelegate {

    func requestFailed(for extensionContext: CXCallDirectoryExtensionContext, withError error: Error) {
        // An error occurred while adding blocking or identification entries, check the NSError for details.
        // For Call Directory error codes, see the CXErrorCodeCallDirectoryManagerError enum in <CallKit/CXError.h>.
        //
        // This may be used to store the error details in a location accessible by the extension's containing app, so that the
        // app may be notified about errors which occured while loading data even if the request to load data was initiated by
        // the user in Settings instead of via the app itself.
    }

}

これでこの080xxxxyyyyから着信を受けると・・・
IMG_0088_2.png

Blocking Incoming Calls

When a phone receives an incoming call, the system first consults the user’s block list to determine whether a call should be blocked. If the phone number is not on a user- or system-defined block list, the system then consults your app’s Call Directory extension to find a matching blocked number. This is useful for apps that, for example, maintain a database of known solicitors, or allow the user to block any numbers that match a set of criteria.

着信時に、まずシステムは自身がもつ着信拒否リストを参照します。(設定 -> 電話 -> 着信拒否設定の所だと思う)もし、システムが定義している着信拒否リストにその番号がなければ、あなたのアプリの Call Directory extensionを参照して、着信拒否する番号なのかを検索します。これは、知られている弁護士(勧誘員??)のデータベースを維持する(???)か、一連の基準にマッチした電話番号を全て拒否する時に有用です。

(知られている弁護士 ?)

思ったこと

でもやっぱり、

Because this method is called only when the system launches the app extension and not for each individual call, you must specify call identification information all at once;

これがきになる。app extension起動ってどこなんだろう、終了して、再起動するまで発信者識別情報を更新できないって、電話番号が更新されたりするアプリを作れないってことなのだろうか。そう考えると、Apple Storeアプリのようなリアルな店をもつとこが自分の店舗の電話番号登録しておいて使うくらいしか用途なさそう。誤訳だったらごめんなさい。

shintarogit-on-qiita
モバイルアプリケーションエンジニア。iOSとAndroid。しかし自分のスマホはiPhoneなのでそっちやりたい。AWSやNode.js、Vue.jsもやる。なんかサービス作るとかならわりと好き嫌いなくやる。やる。
Why not register and get more from Qiita?
  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
No 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
ユーザーは見つかりませんでした