Skip to content

Instantly share code, notes, and snippets.

@msepcot
Created April 15, 2017 06:05
Show Gist options
  • Save msepcot/2405eb14a878535dd280174e4ddc5760 to your computer and use it in GitHub Desktop.
Save msepcot/2405eb14a878535dd280174e4ddc5760 to your computer and use it in GitHub Desktop.
Exploring the CallKit blocking feature
//
// CallDirectoryHandler.swift
// SelectiveHearing.BlockEveryone
//
// Created by Michael Sepcot on 4/14/17.
// Copyright © 2017 Michael Sepcot. All rights reserved.
//
import Foundation
import CallKit
struct USPhoneNumber: Sequence, IteratorProtocol {
let areaCodes = [
201, 202, 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 218, 219, 224, 225, 228, 229, 231, 234, 239, 240,
248, 251, 252, 253, 254, 256, 260, 262, 267, 269, 270, 272, 276, 281, 301, 302, 303, 304, 305, 307, 308, 309, 310, 312, 313,
314, 315, 316, 317, 318, 319, 320, 321, 323, 325, 330, 331, 334, 336, 337, 339, 340, 346, 347, 351, 352, 360, 361, 385, 386,
401, 402, 404, 405, 406, 407, 408, 409, 410, 412, 413, 414, 415, 417, 419, 423, 424, 425, 430, 432, 434, 435, 440, 442, 443,
458, 469, 470, 475, 478, 479, 480, 484, 501, 502, 503, 504, 505, 507, 508, 509, 510, 512, 513, 515, 516, 517, 518, 520, 530,
531, 534, 539, 540, 541, 551, 559, 561, 562, 563, 567, 570, 571, 573, 574, 575, 580, 585, 586, 601, 602, 603, 605, 606, 607,
608, 609, 610, 612, 614, 615, 616, 617, 618, 619, 620, 623, 626, 630, 631, 636, 641, 646, 650, 651, 657, 660, 661, 662, 667,
669, 670, 671, 678, 681, 682, 684, 701, 702, 703, 704, 706, 707, 708, 712, 713, 714, 715, 716, 717, 718, 719, 720, 724, 725,
727, 731, 732, 734, 737, 740, 747, 754, 757, 760, 762, 763, 765, 769, 770, 772, 773, 774, 775, 779, 781, 785, 786, 787, 801,
802, 803, 804, 805, 806, 808, 810, 812, 813, 814, 815, 816, 817, 818, 828, 830, 831, 832, 843, 845, 847, 848, 850, 856, 857,
858, 859, 860, 862, 863, 864, 865, 870, 872, 878, 901, 903, 904, 906, 907, 908, 909, 910, 912, 913, 914, 915, 916, 917, 918,
919, 920, 925, 928, 929, 931, 936, 937, 938, 939, 940, 941, 947, 949, 951, 952, 954, 956, 970, 971, 972, 973, 978, 979, 980,
984, 985, 989
]
var index = 0
var phoneNumber = 0
mutating func next() -> CXCallDirectoryPhoneNumber? {
if phoneNumber > 999_9999 {
phoneNumber = 0
index += 1
}
if index == areaCodes.count {
return nil
} else {
defer { phoneNumber += 1 }
if let phoneNumber11 = NumberFormatter().number(from: String(format: "1%.3d%.7d", areaCodes[index], phoneNumber)) {
return CXCallDirectoryPhoneNumber(phoneNumber11)
}
return nil
}
}
}
class CallDirectoryHandler: CXCallDirectoryProvider {
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
}
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 = USPhoneNumber()
for phoneNumber in phoneNumbers {
context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
}
}
}
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.
}
}
@msepcot
Copy link
Author

msepcot commented Apr 15, 2017

Turns out CallKit doesn't like it when you try to add 3 billion numbers to the block list. Go figure.

@msepcot
Copy link
Author

msepcot commented Apr 15, 2017

It was a fun exercise to build the USPhoneNumber war dialer as a sequence iterator.

@ryan2clw
Copy link

There's less than ten million numbers in the US and you forgot to put them in ascending order, which is why it won't work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment