ガラケーからiPhoneへ電話帳を移行した話

# はじめに

私はプライベートの電話を2回線契約しています。1つ目は昔から契約している大手キャリアの電話+キャリアメール用、もう1つはいわゆる格安SIMの契約で主にデータ通信用です。前者にはだいぶ古いフィーチャーフォン(いわゆるガラケー)を、後者にはiPhoneを使っています。で、今回同じ構成の家族が晴れて(?)契約を一本化することになり、その際「ガラケーの電話帳をiPhoneに移行してほしい」と言われたのでやってみたところ、いくつか技術的な問題に遭遇したのでここに解決方法を記しておきます。(もうそんなことで困る人少ないでしょうけども。）

ちなみに、今回は大手キャリアから格安SIMへMNPで移行したのですが、全てオンラインで処理が完結しました。なのでこの電話帳の移行もショップへ行くことなく終わらせたいということで作業した記録になります。恐らくショップでならケーブルを繋いで移行できる機械が使えるのではないかと思います(もちろん試してはいませんし、既に解約してるキャリアのショップに行くのはそれはそれで少し気が引けます)。

# 移行計画

さてまずどうやって電話帳を移行するかを検討します。遠い昔であればガラケーをPCに繋いで電話帳を管理するソフトウェアとかもありましたが、さすがに今更それを(買って)使うのもなんですので別の方法を探します。MNPの処理は既に完了しているのでモバイルネットワーク通信で送ることもできません。赤外線はiPhone側がないので受け取れないですね。Bluetoothでも無理なようです。

そこで今回は一番単純で確実と思われる以下の方法にしました。
1. ガラケーから電話帳をSDカードにexportする
1. SDカードに保存した電話帳をPCに読み込む
1. 電話帳情報をiCloud連絡先にロードする

iCloud連絡先にロードできれば、iPhoneから直接その連絡先を参照できますので問題ないと考えられます。

# ガラケーから電話帳をexport

これはもちろん機種によって違うと思いますが、今回試した機種では
1. 「電話帳」を開く
1. 「全検索」(どれでもいいので選ぶ)
1. 「サブメニュー」を選択
1. 「microSDへコピー」を選択
1. 「全コピー」を選択

完了すると電話帳がファイルとしてSDカードに保存されます。

# 電話帳をPCに読み込む

電話帳をコピーしたSDカードをPCに接続してコピーします。もしかすると機種によって違うのかもしれませんが、私の場合は`SD_PIM`というディレクトリの中にファイルがありました。`.vcf`という拡張子になっているファイルです(以下「元データ」と呼びます)。中を開いてみると以下のような文字が並んでいます。

```
BEGIN:VCARD
VERSION:2.1
N;CHARSET=SHIFT_JIS:<8F>ƈ䕶<95>F;;;;
SOUND;X-IRMC-N;CHARSET=SHIFT_JIS:<C3>ٲ<CC><D0>˺;;;;
TEL;VOICE:080????????
TEL:
TEL:
TEL:
TEL:
EMAIL;INTERNET:?????@gmail.com
EMAIL:
EMAIL:
EMAIL:
EMAIL:
ADR:
NOTE:
BDAY:
X-NEC-ALARM:
PHOTO:
X-NO:94
X-CLASS:PUBLIC
X-DCM-DATALINKID:
X-DCM-ADR:
X-DCM-NOTE:
X-DCM-URL:
END:VCARD
```
(電話番号等はマスクしています)

既にいくつか問題が見えますが、後ほど説明していきます。

こちらのフォーマットは[RFC 6350](https://www.rfc-editor.org/rfc/rfc6350.html)で規定されているvCardというフォーマットになります。定義によると

> representing and exchanging a variety of information about individuals and other entities (e.g., formatted and structured name and delivery addresses, email address, multiple telephone numbers, photograph, logo, audio clips, etc.)

とありますので、大まかに訳すならば

> 名前、住所、メールアドレス、電話番号など個人などに関する様々な情報を表現しやり取りする

ためのデータ・フォーマットということになります。早速これをiCloud連絡帳へimportしていきます。

# iCloud連絡帳へのimport

先ほど取得したファイルをアップロードするため、[iCloud](https://icloud.com)にPCからログインします。

![スクリーンショット 2022-09-21 20.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632713/00df4daf-e13c-31da-d5da-d0801d028137.png)

ログインするとこんな感じの画面になると思います。

![スクリーンショット 2022-09-21 20.13.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632713/ab3b1e75-6fbe-1404-1d7a-e8141a3dd7f4.png)

「連絡先」をクリックし、右下の歯車マークのメニューから「vCardを読み込む…」をクリックし、先ほど取得したファイルをアップロードします。
![スクリーンショット 2022-09-21 20.17.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632713/45937711-2c89-128e-9b84-8f884308805f.png)

お分かりのこととは思いますが(そもそもこれでうまく行くようならこの記事はほぼ不要ですので)、読み込みに失敗しました。ですが見ての通りエラーはあまり親切ではないので原因の特定を行って対応していきます。

# Importするための変換
## UTF-8へ変換

エラーの直接の原因ではないと考えられますが、そもそも日本語の名前が文字化けしているのを直しておいた方がよさそうです。元データはShift JISで書かれているようなのですが[RFC 6350 Section 3.1](https://www.rfc-editor.org/rfc/rfc6350.html#section-3.1)によると、(以下抜粋)

> The charset for vCard is UTF-8 as defined in RFC3629.  There is no way to override this.

ということですので、UTF-8にするべきでしょう。Shift JISをUTF-8に変換できるのであれば方法は問いません。私は今回Visual Studio Code(VSCode)がインストールしてある環境だったのでVSCodeにお任せしてみました。VSCodeで"Change File Encoding"を選びます。
![スクリーンショット 2022-09-21 23.53.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632713/b817a082-3664-ee61-af70-4021f80a3e77.png)

それから"Reopen with Encoding"メニューから"Japanese (Shift JIS)"を選べば、以下のようにちゃんとファイルが開けました。
![スクリーンショット 2022-09-21 23.53.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632713/84b30e5c-c996-a9c7-b5d1-e3d52e65eb73.png)

ただこのままではShift JISでエンコードされているファイルを開いているだけなので、UTF-8で保存し直します。右下の"Shift JIS"と書かれているところをクリックし、"Save with Encoding"から"UTF-8"を選んで変換終了です。

## 正常なフォーマットの確認
iCloud連絡先に正しく読み込ませるには、一番手っ取り早い方法としてiCloud連絡先からvCard形式にexportして正常に受け付けられるフォーマットを確認することです。iCloud連絡先を開き、どれかの連絡先を選んで左下の歯車アイコンのメニューから「vCardを書き出す…」を選びます。
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632713/352efdba-76d9-3f85-a8b4-472729403129.png"/>

ファイルの中身を確認してみます。
```
BEGIN:VCARD
VERSION:3.0
N:照井;文彦;;;
FN:文彦 照井
X-PHONETIC-FIRST-NAME:ふみひこ
X-PHONETIC-LAST-NAME:てるい
TEL;TYPE=CELL;TYPE=pref;TYPE=VOICE:080 **** ****
EMAIL;TYPE=HOME;TYPE=pref;TYPE=INTERNET:********@gmail.com
PRODID:-//Apple Inc.//iCloud Web Address Book 2223B25//EN
REV:2022-09-21T08:03:39Z
END:VCARD
```
ここから恐らく想定されるのはVersionが3.0(以上?)でないといけないということですね。元データは2.1でした。また、[RFC 6350 Section 3.3](https://www.rfc-editor.org/rfc/rfc6350.html#section-3.3)によると、

> A vCard object MUST include the VERSION and FN properties.
(vCardオブジェクトはVERSIONとFNを含まなければならない。)

とありますので、FNも生成しないといけないようです。確かに元データにはFNは存在していないのでエラーになったようです。これらを付与していきます。

## FNの生成とバージョンの更新

FNはformatted nameの略のようなので、とりあえずフルネームを入れておけばよさそうです。元データはNという項目に名前が入っているので、これを元に生成するのがよさそうです。

> N;CHARSET=SHIFT_JIS:照井文彦;;;;

こちらの書式は機種によって違う可能性がありますが、私の機種だと電話帳に姓と名の区別がなかったのでこのような形になっていたようです。区別がないのでここではフルネームが姓として登録されることになります。区別がある機種であればセミコロンの入り方が異なるはずで、そうなっていれば姓と名が区別されてロードされることになります。iCloud連絡先はまさにその形ですね。

また、後でわかったのですが、ここで`CHARSET=SHIFT_JIS`を残しておくとiPhone上では文字化けすることがわかりました。iCloud連絡先では特に問題ないのでiCloud上では無視されるようです。ファイルはUTF-8に変換したのでこちらもここで外しておきます。変換もなんでもいいのですが今回は簡単に`sed`を使います。In placeオプション(`-i`)を使って変換してもいいのですが、変換内容を確認するため別ファイルにしています。

```shell
% sed 's|^N;[^:]*:\(.*\);;;;|N:\1;;;;\nFN:\1|' PIM00002.VCF > PIM00003.VCF
% diff PIM0000[23].VCF                                                    
3c3,4
< N;CHARSET=SHIFT_JIS:照井文彦;;;;
---
> N:照井文彦;;;;
> FN:照井文彦
```
想定した通り変換されてることが確認できました。

同様にVERSIONも2.1から3.0に変更します。
```shell
% sed 's|VERSION:2.1|VERSION:3.0|' PIM00003.VCF > PIM00004.VCF
% diff PIM0000[34].VCF
2c2
< VERSION:2.1
---
> VERSION:3.0
```
この時点でiCloud連絡先にアップロードすると無事エントリが追加されているのが確認できます。

## その他の調整

アップロードしたエントリを確認すると、電話番号は登録されていますが、メールアドレスが登録されていません(これもiPhone上では表示されます)。iCloud連絡先の実装は公開されていないので何が失敗しているのかは不明ですが、元データでは
```
EMAIL;INTERNET:?????@gmail.com
```
となっているアドレス情報はiCloud連絡先から書き出したものでは
```
EMAIL;TYPE=HOME;TYPE=pref;TYPE=INTERNET:********@gmail.com
```
のようになっているので、`TYPE=`が必要そうです。

```
% sed 's|EMAIL;INTERNET:\(.*\)$|EMAIL;TYPE=HOME:\1|' PIM00004.VCF > PIM00005.VCF
% diff PIM0000[45].VCF                                                          
11c11
< EMAIL;INTERNET:********@gmail.com
---
> EMAIL;TYPE=HOME:********@gmail.com
```

これでロードすると正しくメールアドレスも登録されました。その他のタイプもありましたので適宜置き換えました。

ふりがなも登録されていましたので引き継げるようにします。元データでは
```
SOUND;X-IRMC-N;CHARSET=SHIFT_JIS:ﾃﾙｲﾌﾐﾋｺ;;;;
```
なので、iCloud連絡帳の以下のエントリに書き換えます。
```
X-PHONETIC-LAST-NAME:てるい
```

変換するsedは以下のようになります。

```
% sed 's|^SOUND[^:]*:\(.*\);;;;|X-PHONETIC-LAST-NAME:\1|' PIM00005.VCF > PIM00006.VCF
% diff PIM0000[56]*
5c5
< SOUND;X-IRMC-N;CHARSET=SHIFT_JIS:ﾃﾙｲﾌﾐﾋｺ;;;;
---
> X-PHONETIC-LAST-NAME:ﾃﾙｲﾌﾐﾋｺ
```
私は半角カナだと気になるので全角に変換してから登録しましたが、それは必須ではないです。

# まとめ

フィーチャーフォンの電話帳(vCard 2.1)からiCloud電話帳(vCard 3.0)への変換についてまとめました。必須の項目だけを押さえたら後はマップしたい対象のプロパティをどのように設定すればいいのかをiCloud電話帳側で作成したエントリを書き出すことで確認できるので、ここに記述してないプロパティについても移行可能だと思います。必要な方の一助になれば幸いです。