[
  {
    "path": ".gitignore",
    "content": "\n# Created by https://www.gitignore.io/api/swift,appcode,xcode,osx\n\n### Swift ###\n# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## Build generated\nbuild/\nDerivedData\n\n## Various settings\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n\n## Other\n*.xccheckout\n*.moved-aside\n*.xcuserstate\n*.xcscmblueprint\n\n## Obj-C/Swift specific\n*.hmap\n*.ipa\n\n## Playgrounds\ntimeline.xctimeline\nplayground.xcworkspace\n\n# Swift Package Manager\n#\n# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.\n# Packages/\n.build/\n\n# CocoaPods\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\n# Pods/\n\n# Carthage\n#\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\nCarthage/Build\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the \n# screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md\n\nfastlane/report.xml\nfastlane/screenshots\n\n\n### AppCode ###\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm\n\n*.iml\n\n## Directory-based project format:\n.idea/\n# if you remove the above rule, at least ignore the following:\n\n# User-specific stuff:\n# .idea/workspace.xml\n# .idea/tasks.xml\n# .idea/dictionaries\n# .idea/shelf\n\n# Sensitive or high-churn files:\n# .idea/dataSources.ids\n# .idea/dataSources.xml\n# .idea/sqlDataSources.xml\n# .idea/dynamic.xml\n# .idea/uiDesigner.xml\n\n# Gradle:\n# .idea/gradle.xml\n# .idea/libraries\n\n# Mongo Explorer plugin:\n# .idea/mongoSettings.xml\n\n## File-based project format:\n*.ipr\n*.iws\n\n## Plugin-specific files:\n\n# IntelliJ\n/out/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n\n\n### Xcode ###\n# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## Build generated\nbuild/\nDerivedData\n\n## Various settings\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n\n## Other\n*.xccheckout\n*.moved-aside\n*.xcuserstate\n\n\n### OSX ###\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\r\r\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n"
  },
  {
    "path": "PhoneticContacts.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tD744DD001C6738BD00D01E04 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D744DCFF1C6738BD00D01E04 /* main.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\tD7E7F1C71661184E008C3C32 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = /usr/share/man/man1/;\n\t\t\tdstSubfolderSpec = 0;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 1;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\tD744DCFF1C6738BD00D01E04 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = \"<group>\"; };\n\t\tD7E7F1C91661184E008C3C32 /* PhoneticContacts */ = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.executable\"; includeInIndex = 0; path = PhoneticContacts; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tD7E7F1C61661184E008C3C32 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tD7E7F1BE1661184E008C3C32 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD744DCFF1C6738BD00D01E04 /* main.swift */,\n\t\t\t\tD7E7F1CA1661184E008C3C32 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tD7E7F1CA1661184E008C3C32 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD7E7F1C91661184E008C3C32 /* PhoneticContacts */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tD7E7F1C81661184E008C3C32 /* PhoneticContacts */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = D7E7F1D81661184E008C3C32 /* Build configuration list for PBXNativeTarget \"PhoneticContacts\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tD7E7F1C51661184E008C3C32 /* Sources */,\n\t\t\t\tD7E7F1C61661184E008C3C32 /* Frameworks */,\n\t\t\t\tD7E7F1C71661184E008C3C32 /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = PhoneticContacts;\n\t\t\tproductName = PhoneticContacts;\n\t\t\tproductReference = D7E7F1C91661184E008C3C32 /* PhoneticContacts */;\n\t\t\tproductType = \"com.apple.product-type.tool\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tD7E7F1C01661184E008C3C32 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 0720;\n\t\t\t\tLastUpgradeCheck = 0900;\n\t\t\t\tORGANIZATIONNAME = \"Lex Tang\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tD7E7F1C81661184E008C3C32 = {\n\t\t\t\t\t\tLastSwiftMigration = 0900;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = D7E7F1C31661184E008C3C32 /* Build configuration list for PBXProject \"PhoneticContacts\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = D7E7F1BE1661184E008C3C32;\n\t\t\tproductRefGroup = D7E7F1CA1661184E008C3C32 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tD7E7F1C81661184E008C3C32 /* PhoneticContacts */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tD7E7F1C51661184E008C3C32 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tD744DD001C6738BD00D01E04 /* main.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\tD7E7F1D61661184E008C3C32 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tD7E7F1D71661184E008C3C32 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Owholemodule\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tD7E7F1D91661184E008C3C32 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = On;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tD7E7F1DA1661184E008C3C32 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = On;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tD7E7F1C31661184E008C3C32 /* Build configuration list for PBXProject \"PhoneticContacts\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tD7E7F1D61661184E008C3C32 /* Debug */,\n\t\t\t\tD7E7F1D71661184E008C3C32 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tD7E7F1D81661184E008C3C32 /* Build configuration list for PBXNativeTarget \"PhoneticContacts\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tD7E7F1D91661184E008C3C32 /* Debug */,\n\t\t\t\tD7E7F1DA1661184E008C3C32 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = D7E7F1C01661184E008C3C32 /* Project object */;\n}\n"
  },
  {
    "path": "PhoneticContacts.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:PhoneticContacts.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "PhoneticContacts.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>BuildSystemType</key>\n\t<string>Latest</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "README.md",
    "content": "# PhoneticContacts\n\n![Language](https://img.shields.io/badge/Language-Swift%204-orange.svg)\n[![Git](https://img.shields.io/badge/GitHub-lexrus-blue.svg?style=flat)](https://github.com/lexrus)\n[![Twitter](https://img.shields.io/badge/Twitter-@lexrus-blue.svg?style=flat)](http://twitter.com/lexrus)\n\n为你的联系人加上拼音属性，\n这样即使你的 iPhone 设置成英文，\n也能有__按姓氏拼音首字母分段__的功能。\n\n这个工具参考了 [V2EX 网友写的 AppleScript](http://v2ex.com/t/52860)，\n但使用 CFStringTransform 查拼音，速度更快。\n\n另外，有些汉字姓氏的读音比较特殊 (如「曾」作为姓时读作 zeng)。\n我在网上随便找了一些，做了替换的处理，可能不全，欢迎补充。\n\n请在 Xcode 9 里打开此项目，command + r 运行后联系人就有拼音属性了。\n过不了多久(看脸)，这些更新后的联系人会通过 iCloud 同步到 iPhone。\n\n"
  },
  {
    "path": "main.swift",
    "content": "//\n//  main.swift\n//  PhoneticContacts\n//\n//  Created by Lex on 2/7/16.\n//  Copyright © 2016 Lex Tang. All rights reserved.\n//\n\nimport Foundation\nimport AddressBook\n\nextension String {\n\n    func upcaseInitial() -> String {\n        guard let firstChar = first else { return \"\" }\n        return String(firstChar).uppercased() + dropFirst()\n    }\n\n    func phonetic() -> String {\n        let src = NSMutableString(string: self) as CFMutableString\n        CFStringTransform(src, nil, kCFStringTransformMandarinLatin, false)\n\n        // Transform NínHǎo to NinHao\n        CFStringTransform(src, nil, kCFStringTransformStripCombiningMarks, false)\n\n        let s = src as String\n        if s != self {\n            return s\n                .components(separatedBy: \" \")\n                .map { $0.upcaseInitial() }\n                .reduce(\"\", +)\n        }\n\n        return self\n    }\n\n    func phoneticLast() -> String {\n        let SpecialLastName: [String: String] = [\n            \"柏\": \"bai\",\n            \"鲍\": \"bao\",\n            \"贲\": \"ben\",\n            \"秘\": \"bi\",\n            \"薄\": \"bo\",\n            \"卜\": \"bu\",\n            \"岑\": \"cen\",\n            \"晁\": \"chao\",\n            \"谌\": \"chen\",\n            \"种\": \"chong\",\n            \"褚\": \"chu\",\n            \"啜\": \"chuai\",\n            \"单\": \"chan\",\n            \"郗\": \"chi\",\n            \"邸\": \"di\",\n            \"都\": \"du\",\n            \"缪\": \"miao\",\n            \"宓\": \"mi\",\n            \"费\": \"fei\",\n            \"苻\": \"fu\",\n            \"睢\": \"sui\",\n            \"区\": \"ou\",\n            \"华\": \"hua\",\n            \"庞\": \"pang\",\n            \"查\": \"zha\",\n            \"佘\": \"she\",\n            \"仇\": \"qiu\",\n            \"靳\": \"jin\",\n            \"解\": \"xie\",\n            \"繁\": \"po\",\n            \"折\": \"she\",\n            \"员\": \"yun\",\n            \"祭\": \"zhai\",\n            \"芮\": \"rui\",\n            \"覃\": \"tan\",\n            \"牟\": \"mou\",\n            \"蕃\": \"pi\",\n            \"戚\": \"qi\",\n            \"瞿\": \"qu\",\n            \"冼\": \"xian\",\n            \"洗\": \"xian\",\n            \"郤\": \"xi\",\n            \"庹\": \"tuo\",\n            \"彤\": \"tong\",\n            \"佟\": \"tong\",\n            \"妫\": \"gui\",\n            \"句\": \"gou\",\n            \"郝\": \"hao\",\n            \"曾\": \"zeng\",\n            \"乐\": \"yue\",\n            \"蔺\": \"lin\",\n            \"隽\": \"juan\",\n            \"臧\": \"zang\",\n            \"庾\": \"yu\",\n            \"詹\": \"zhan\",\n            \"禚\": \"zhuo\",\n            \"迮\": \"ze\",\n            \"沈\": \"shen\",\n            \"沉\": \"shen\",\n            \"尉迟\": \"yuchi\",\n            \"长孙\": \"zhangsun\",\n            \"中行\": \"zhonghang\",\n            \"万俟\": \"moqi\",\n            \"单于\": \"chanyu\"\n        ]\n\n        if let specialLastName = SpecialLastName[self] {\n            return specialLastName.upcaseInitial()\n        }\n        return self\n    }\n\n}\n\nlet ab = ABAddressBook()\nab.people().forEach {\n    guard let people = $0 as? ABPerson else {\n        return\n    }\n\n    if let lastName = people.value(forProperty: kABLastNameProperty) as? String {\n        _ = try? people.setValue(\n            lastName.phoneticLast().phonetic(),\n            forProperty: kABLastNamePhoneticProperty,\n            error: ()\n        )\n        print(lastName, lastName.phoneticLast().phonetic(), separator: \"->\", terminator: \", \")\n    }\n\n    if let firstName = people.value(forProperty: kABFirstNameProperty) as? String {\n        _ = try? people.setValue(\n            firstName.phonetic(),\n            forProperty: kABFirstNamePhoneticProperty,\n            error: ()\n        )\n        print(firstName, firstName.phonetic(), separator: \"->\", terminator: \" | \")\n    }\n}\nab.save()\n"
  }
]