It is a workshop for iOS developers, macOS developers, that have never used Objective-C XPC interface for inter-process communication.
Attendees developed a 'Magic 8 Ball' application: similar to a popular fortune-telling toy 🎱
The starter project contains a UI application with a window similar to a ball. Try to double-click it, and it will shake.
The goal is to develop a background process and setup communication with it.
For this part, omit instructions, surrounded with/// --- PART 2 ---
- Download starter project.
- Launch it, see, what it has.
- Add
MagicBallBackgroundService
target (choose Cocoa Application). - Remove the window from it's MainMenu.xib or Main.storyboard (whichever you have)
- Add a key-value pair to it's Info.plist: 'Application is background only' : YES
- Go to
MagicBallBackgroundService
target's capabilities and switch App Sandbox off.
Sidenote 1: XPC works with Sandbox enabled, just another setup is required.
Sidenote 2: We should set 'Application is background only' because we don't want any Dock icon or Main menu in the Menu bar.
- Go to Client app's
Build Phases
and
- add
MagicBallBackgroundService
to Dependencies list - add a new
Copy Files
phase withDestination:
Wrapper
; setSubpath
:Contents/Library/LoginItems
. Press+
and addMagicBallBackgroundService.app
- Locate
additional_files
direcory in the project root firectory. - Add
IPC.swift
to both targets - Set the
kServiceName
constant to the Bundle identifier of the Service
- Go to
AppController
class and implement:
start()
stop()
connect()
getDecision()
- Download
Magic8BallService.swift
andMagic8Ball.swift
- Add them to the Service target
- Implement
start()
,stop()
,listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool
andgetDecision(replyBlock: @escaping DecisionReplyBlock)
- In the AppDelegate class make a property of
Magic8BallService
instance. - Call
start()
on this instance inapplicationDidFinishLaunching()
. - Call
stop()
on this instance inapplicationWillTerminate()
Run the Client target. Think of a Yes-No question and double-click the ball to see if you get the answer.
Let's say, that background service wants to send the user 'Signs' about their future. To do that it needs to be able to call the Client application and pass it the 'Sign'.
- Go through the project and follow the instructions, surrounded by
/// --- PART 2 ---
Notes:
- open
Activity Monitor
application and search for 'magic' to see, if both apps are running - in order to terminate the background service you should manually quit the main application
- the background service is not automatically attached to Xcode. You can attach to it manually or add some
NSLog()
logs and see them in theConsole
application