Use Swift iOS CallKit and Realm. Attempts to share realm info between app and Call Directory extension did not work well.
Apple WWDC 2016 Session 230 https://developer.apple.com/videos/play/wwdc2016/230/
Apple WWDC 2015 Session 224 https://developer.apple.com/videos/play/wwdc2015/224/
Apple sample code https://developer.apple.com/library/content/samplecode/Speakerbox/Introduction/Intro.html
Apps can create a Call Directory app extension to identify and block incoming callers by their phone number.
https://developer.apple.com/documentation/callkit?preferredLanguage=occ
https://forums.developer.apple.com/thread/48837
Hotline.app note CallDirectoryHandler.swift is ~99% identical to Xcode Call Directory app extension template code. https://www.raywenderlich.com/150015/callkit-tutorial-ios
https://github.com/beepscore/RealmSwiftExamples.git
Add a class similar to Realm: CRUD | Swift 4, Xcode 9 https://www.youtube.com/watch?v=hC6dLLbfUXc
CallKit requires an iPhone, doesn't work on simulator.
App uses to report to system know about "out of band" notifications. Not user actions but external events such as - an incoming call coming to the app - an outgoing call connected - a call ended on remote side
CXProvider uses CXCallUpdate to communicate to system. System uses CXAction to communicate user actions to CXProvider.
In CallKitty, ProviderDelegate has a CXProvider.
App uses to make requests to system. Handles local user actions such as - request to start a call - request to answer a call - request to end a call
CXCallController uses CXTransaction containing CXAction(s) to communicate to system.
In CallKitty, CallKittyCallManager has a CXCallController.
- network VOIP phone call comes to app
- app CXProvider sends CXCallUpdate to system
- system publishes event, others can observe including system Phone.app UI
- if user answers call, Phone.app UI sends answer action to system
- system sends CXAnswerCallAction to app CXProvider.
- app answers call on network
- in app UI, user requests to end call
- app CXCallController sends CXTransaction(CXEndCallAction) to system
- system checks request
- if system approves request, system sends CXEndCallAction back to app CXProvider
"The principal object for a Call Directory app extension for a host app." In CallKitty, CallDirectoryHandler subclasses CXCallDirectoryProvider
Shouldn't need to run scheme CallKittyDirectoryExtension first to update block and id lists, normal user is not going to do this.
Run scheme CallKitty on phone.
Settings app / Phone / Call Blocking & Identification / Allow these apps to block calls and provide caller id Enable CallKitty
If app alerts allow microphone tap OK.
To hit breakpoints in CallDirectoryHandler, run scheme CallKittyDirectoryExtension and choose app CallKitty. App may need to call reloadExtension.
Don't call it, let iOS call it? https://stackoverflow.com/questions/43951781/callkit-extension-begin-request
CXCallDirectoryExtensionContext objects are not initialized directly, but are instead passed as arguments to the CXCallDirectoryProvider instance method beginRequest(with:).
simulate incoming call from a blocked phone number e.g. 1_408_555_5555
simulate incoming call from an identified phone number e.g. 1_877_555_5555
In this prototype I used a realm in a local file (git tag realm-local). I think the Call Directory Extension realm can't see the CallKitty app realm database file.
To try to fix this, in the app I made an app group and used it to make a storage directory. In target CallKitty / Capabilities / App Groups I added group.com.beepscore.CallKitty. (git commit f1cf015)
Then in RealmService I added configuration() to set file url and used it when instantiating a realm. (git commit 8aa5446) However target CallKittyDirectoryExtension got nil when it attempted to use the file path.
Apple App extension programming guide says app and extension can use app group to share things like user defaults. This may not perform well with a large amount of data, but might be useful as a way to pass small amounts of data such as number of blocked phone numbers or user entered phone numbers for incremental block or identify.
Also Xcode build failed when I tried adding the app group to the extension.
In production, the app and/or the app extension could talk with an external realm platform server. If both the app and the app extension talk with the same realm server, then they can access the same database.
Also can use multiple realms. For example, could have a realm for blocked and identified callers common to all users. Could have another realm or realms per user, for blocked and identified callers they added. https://stackoverflow.com/questions/42863366/downsides-to-multiple-realm-files-databases
The app and the app extension talk with a realm object server. In initial tests the extension seems like it isn't updating the data.
I heard realm engineers said Realm may not communicate correctly between an app and its CallKit extension.
App extension programming guide / Handling common scenarios / Sharing data with your containing app https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html "Even though an app extension bundle is nested within its containing app’s bundle, the running app extension and containing app have no direct access to each other’s containers. You can, however, enable data sharing."
https://academy.realm.io/posts/tutorial-sharing-data-between-watchkit-and-your-app/ http://tackmobile.com/blog/App-Groups-and-iMessage-Extensions-for-iOS-10.html
https://realm.io/docs/swift/latest/
https://github.com/realm/realm-cocoa
I forked realm-cocoa, added branch beepscore, updated 2 projects to recommended settings. Xcode says "conversion to Swift 4 is available". Every time I tap it Xcode crashes.
https://stackoverflow.com/questions/44640852/how-can-i-use-realm-with-swift-4/44641478#44641478
Also might need to clone recursive.
Try download framework instead.
2017-11-06 got error module compiled with Swift 4.0 cannot be imported in Swift 4.0.2 https://stackoverflow.com/questions/47051318/realms-swift-module-compiled-with-swift-4-0-cannot-be-imported-in-swift-4-0-2
My Xcode is using Swift 4.0.2, not 4.0
xcrun swift --version
Apple Swift version 4.0.2 (swiftlang-900.0.69.2 clang-900.0.38)
Target: x86_64-apple-macosx10.9
So need to compile from source. Try Carthage.
brew install carthage
carthage update
*** Fetching realm-cocoa
*** Downloading realm-cocoa.framework binary at "v3.0.1"
*** Skipped installing realm-cocoa.framework binary due to the error:
"Incompatible Swift version - framework was built with 4.0 (swiftlang-900.0.65 clang-900.0.37) and the local version is 4.0.2 (swiftlang-900.0.69.2 clang-900.0.38)."
*** Checking out realm-cocoa at "v3.0.1"
*** xcodebuild output can be found in /var/folders/g4/6bm303dn22n5tqj7jrdxrb5w0000gn/T/carthage-xcodebuild.QpIZ4e.log
*** Building scheme "Realm" in Realm.xcworkspace
*** Building scheme "RealmSwift" in Realm.xcworkspace
created Cartfile.resolved