We have access to many Inter-Process-Communication(IPC) mechanisms in macOS. One of the newest is XPC1. Before XPC a common way to use IPC, and provide services between processes, was through Sockets or Mach Messages (Using Mach Ports).
- Macos App Bundle Structure Software
- Macos App Bundle Structure Checker
- Macos App Bundle Structure Builder
- Macos App Bundle Structure Finder
- Macos App Bundle Structure Tutorial
The Octave App bundle for MacOS X is now ready to run. Create an Installer DMG. The GPL'd dmgCreater is a Mac OS X Application which allows simple and easy creation of customized dmg disk images with custom background images. It ensures the correct presentation of the disk image's content irrespective of the current Finder configuration.
- 1 Answers 1 -Accepted-Accepted-Accepted-Do I need to copy these libs within the appbundle-ant-task. Yes, you should mention all the required libraries in classpath elements. The bundler will then copy them all to the appropriate place inside the bundle (only JAR files that are directly under Contents/Java will go onto the classpath when the bundle is run, JARs in subdirectories are.
- Mac users interested in Work breakdown structure app generally download: GanttProject 2.8 Free One may think that when it comes to project management, there is no easy way of doing things; GanttProject though will prove most skeptics wrong.
- On macOS, a GUI application must be built and run from a bundle, which is a directory structure that appears as a single entity when viewed in the Finder. A bundle for an application typically contains the executable and all the resources it needs. Here is the snapshot of an application bundle structure.
- These are simple instructions on how to find the location of Mac OS X applications by Bundle ID. Step One Launch Terminal from your Applications:Utilities folder. Step Two Input mdfind.
Nowadays, we are encouraged by Apple to use XPC in our applications and frameworks that provide services. Also, Apple, in their code, has updated many of its frameworks, daemons and applications to use XPC.
XPC, as you can imagine, is an excellent tool to learn. In this post, we are going to learn:
- How to use XPC in our applications to break it into small modules that provide services that can be requested only when needed. Imagine an app that has code dedicated to a specific task. But the task is seldom used. The application doesn't need to have that code always in memory, increasing the process' memory footprint. We can use XPC Services (Notice capital S) that provide services that will only be executed when needed. Also, the services can be stopped if the OS needs more memory or if the process has been idle for an extended period.
Let's examine what we can accomplish using XPC.
* You can check the full code in the GitHub Repository
*Update: You can check the following post if you are interested in creating a Launch Agent that provides XPC services.
Table of Contents
- Creating a macOS application that includes an XPC Service
XPC provides us with a new abstraction for Inter-Process-Communication, a simple abstraction that on its own it's convenient (using
MIG
is complicated). But aside from having an easier to use IPC mechanism, XPC implementation also gives us some additional benefits. We'll examine the benefits later but first, let's explore some use-cases of XPC.As mentioned before, the XPC mechanism offers an alternative to sockets (or Mach Services using
MIG
) for IPC. We could have, for example, a process that acts as a 'server' waiting for clients to access it's API and provide some service.Imagine we have an application that handles the user's contacts. The app provides an API that you could access from your applications and query for details on the user's contacts. That example could very easily be an XPC service provided by
AddressBook.app
. We don't access the XPC service directly we use the API provided by Contacts.framework
, but the framework is based on XPC services.XPC services used in this way are an excellent way to communicate different processes. The exchange of data in XPC is through
Plists
, that also allows for data type validation.When we talk about XPC Services (capital 'S'), we are referring to the bundle called XPC Service. Bundles in Apple ecosystem refers to entities represented by a specific directory structure. The most common Bundle you encounter are Application Bundles. If you right-click on any application (For example
Chess.app
) and select Show content
, what you'll find is a directory structure.Back to XPC, applications can have may XPC Service bundles. You'll find them inside the
Contents/XPCServices/
directory inside the application bundle. You can search in your /Applications
directory and see how many of the applications rely on XPC Services.The XPC Services inside each application provide services that can be easily accessed from the main
Application
. You can also have XPC Services inside Frameworks
(Which are another type of Bundle). You can check the frameworks on your computer for some examples:Using XPC Services in our apps allow us to break some functionality in separate modules (The XPC Service). We could create an XPC Service that can be in charge of running some costly but infrequent tasks. For example, some crypto task to generate random numbers.
Breaking our application into specific services allows us to keep our main application leaner, and also take less memory while running. Only running our XPC Service on demand.
Another additional benefit is that the XPC Service runs on its own process. If that process crashes or it's killed, it doesn't affect our main application. Imagine that your application support user-defined plugins. And the plugins are built using XPC Services. If they are poorly coded and crash, they won't affect the integrity of your main application.
An additional benefit to the XPC Service is that they can have their own entitlements. The application will only require the entitlement when it makes use of a service provided by XPC Service that requires the entitlement. Imagine you have an app that uses location but only for specific features. You could move those features to an XPC Service and add the location entitlement only to that XPC Service. If your user never needs the feature that uses the location, it won't be prompted for permissions, making the use of your app more trustworthy.
Those are some of the benefits of using XPC. Let's see how XPC Services are managed.
We've discussed that the XPC Service can be run on-demand, but who is in charge of managing your XPC Service? Download mysql pro for mac.
launchd
is the first process to run on our system. It is in charge of launching and managing other processes, services and daemons. launchd
is also in charge of scheduling tasks. So it makes sense that launchd
will also be responsible for the management of XPC Services.As I mentioned before, our XPC Service can be stopped if it has been idle for a long time, or be spawned on demand. All the management is done by
launchd
, and we don't need to do anything for it to work.launchd
has information about system-wide resource availability and memory pressure, who best to make decisions on how to most effectively use our system's resources than launchd
. This is an ingenious implementation if you ask me.Ok, enough theory on XPC let's do something practical.
Let's create an application that makes use of an XPC Service. We are going to be using an Agent-based Menu bar application. Much like the application we created on the post 'Understanding a few concepts of macOS applications by building an agent-based (menu bar) app'.
We'll build the application and XPC Service using the Swift Package Manager. If you want a refresher on how to create apps without using Xcode, check that post.
Our XPC Service will provide a function that will obtain our public IP. We'll add the new option to our 'menu bar' application(the new option will call our XPC Service).
I'll go a little faster here until we reach the XPC code, all the rest was covered in the other post.
Start by creating the directory and initialising the Swift project. The name doesn't matter. I'll be using the code on the mentioned post as the base so I'll call my project
XPCSquirrel
as the code before was only Squirrel
:Macos App Bundle Structure Software
As I mentioned, we are going to base our code on the previous
Squirrel
implementation. I'm just going to show you the complete files and not go into detail explaining how they work until we reach the XPC related code.The
main.swift
looks like this:The
AppDelegate.swift
will have this content:We are going to create the Application Bundle and XPC Service bundle by hand. This means that we are going to manually create the
Info.plist
s for each of the bundles. We are going to create them in a directory called SupportFiles
, and then move them to their proper place in the Application and XPC Service bundles.We are creating the bare bones of the bundles, so there is a lot of information missing. The application bundle we'll create, certainly won't get approved by the App Store. But for understanding how everything works is better to only look at what is required.
Create a file
MainInfo.plist
that will host our application bundle's Info.plist
. And add the following content: (LSUIElement
identifies our application as an Agent so that it won't show an icon in the Dock or on the task switcher).Now create the Plist file for our XPC Service. Create a file with the name
XPCInfo.plist
with the following content:Those are the required fields for an XPC Services bundle
Info.plist
file. The CFBundleIndentifier
is used as the service name. Later we'll use that name when locating the service.Your file structure should look something like this:
Ok, now can focus on the code for the XPC Service.
Finally, let's work with XPC.
We are going to add a new target to our
Package.swift
that will represent our XPC Service code.Edit the
Package.swift
and add the new target:Apple podcast app mac. Now let's create a new directory inside
Sources
that will contain our XPC code.Create a new file inside
Sources/ServiceProvider
called main.swift
. This will be our entry point for our XPC Service bundle. From our main
will listen for new connections and handle their requests.The workflow is the following:
(1) We create a listener and (2) set its delegate object. The delegate is in charge of accepting and setting up new incoming connections. Once our listener has a delegate, we call
resume
that will indicate to our listener to (3) start 'listening' for connections.This is how our
main.swift
will look:We haven't created
ServiceDelegate
yet, so let's do that. Our delegate should implement the NSXPCListenerDelegate
protocol that requires the implementation of the listener
function that sets up the incoming connections. listener
has the following signature:The boolean that is returned indicates if the connection was accepted. We can do any validations and then decide if we accept the connection or not.
Ok, let's work on our delegate. Create a new file inside
Sources/ServiceProvider
called ServiceDelegate.swift
and add the following content:First, we set up the exported interface to be represented by the
ServiceProviderXPCProtocol
(we'll be creating that protocol next). This protocol defines the interface for our Service. It defines what functions we provide and their signatures. We are now on the 'server' side of the connection, but in the 'client' side will also need to have the protocol that defines our interface.After setting
exportedInterface
, we create an object that implements our protocol. The object will be the one called when our service functions are requested. We set our connection's exportedObject
property to the Object that implements our protocol.Macos App Bundle Structure Checker
When a new connection is created, it begins its execution life in a stopped state. We use
resume
to start it.If everything went ok, we return
true
to indicate that the connection was accepted and configured.As we decided before, our XPC service will provide a service that obtains our public IP and executes the closure we got as a parameter(
withReply
) with our IP.Create the file
ServiceProviderXPCProtocol.swift
and add the following content: Drake no long talk download.Now, let's create a new file where we'll implement the protocol. Create the file
ServiceProviderXPC.swift
inside Sources/ServiceProvider/
. And add the following content:That function uses the
dig
command to obtain our public IP. The bulk of the code is related to running the dig
command, but the code relevant to XPC is only sending our ip
obtained by dig
to the reply
closure.Alright, we have our XPC Service side complete. Let's work on accessing our XPC Service form the main application.
Using our XPC Service
Apple has done an excellent job making the use of XPC Services very straight forward. The workflow is the following:
(1) We create a connection to the service we want to use. The service is looked up by name (The
CFBundleIdentifier
in the XPC Service's Info.plist
remember?). (2) Set the remote object Interface, here we need to know the protocol that describes the interface, the one we used to create the service on the XPC Service bundle. (3) Get an instance of the object that implements the interface (using remoteObjectProxy
). (4) And last, make use of the service. Remember that the calls are always asynchronous that means if we are going to work with the UI, we need to send it through the main
Queue, so we don't block the main thread.Ok, let's see our implementation. We are going to be working on the
AppDelegate.swift
file. Let's add a new option to the statusBarMenu
that allows us to call the method to display our public IP.We need to define our function,
xpcCall
. Let's do that:Everything about spotify free. As you can see, we are defining the
remoteObjectInterface
using ServiceProviderXPProtocol
, but we haven't defined it yet for the main application. You can copy it from the Sources/ServiceProvider/
directory and paste it in Sources/XPCSquirrel
directory.We are using
connection.remoteObjectProxyWithErrorHandler
that allows us to pass a closure to handle any errors and obtain an instance of the object that implements the ServiceProviderXPCProtocol
.Then we call our function
getPublicIp(withReply:)
using the inline closure syntactic sugar to pass the closure. In the closure we set our statusBarItem.button?.title
to be the ip
we get from the service.Very cool right?
Next, you'll see the full
AppDelegate.swift
file. I also included some additional changes. For example, the option to show the counter. This way, we can go back to using our App as a counter after we've checked our public ip
.We now have all the code, but we still need to put everything together. We need to build the application and add the XPCService to the proper place in the main application's bundle. Application bundles can have as many XPC Service bundles as they need, they are located inside the
XPCServices
folder inside Contents
.I'll automate the process using
make
so we don't have to do it all by hand. You can see the Makefile
next:As you can see, we create all the Application Bundle structure and create the XPC bundle. Let's run the
make
command and generate our XPCSquirrel.app
.This generates the
XPCSquirrel.app
bundle that has the following structure: https://vidtree.weebly.com/blog/mac-app-monitor-eyes.Now you can run the application by double-clicking it on
Finder
or using the open
command on the shell:If you can't see the app in your taskbar, switch to
Finder
, it might be covered by some menu items in your current application. Now you can click Get public ip
, and you should see your IP in the taskbar.Congratulations! You just used XPC Services in your application.
There are more uses for XPC as Inter-Process-Communication, other than creating XPC Service bundles in your applications. One of the most useful, in my opinion, is creating a
LaunchAgent
that provides some services that many apps can connect to and obtain information.For example, an application that does grammar and spelling checking (Grammarly maybe?). The app can expose an XPC service that you can send a block of text, and it'll return an object with the corrections.
Notice the lower-case 's' in that use of XPC service, we are not talking about a bundle but a service that can be accessed from other applications.
https://vidtree.weebly.com/blog/what-app-can-i-edit-pictures-with-mac. Ok, that's it for this week. Let me know if you like the post and any other use you give toXPC.
* You can check the full code in the GitHub Repository
- Apple's documentation no Creating XPC Services, also, Daemons and Services Programming Guide
- I didn't find many resources for XPC aside from Apple's API documentation. There was a lot of trial and error to get it to work. Here is the Apple - XPC documentation
- I have no idea what XPC stands for, if you have any clues, please let me know :). ↩
** If you want to check what else I'm currently doing be sure to follow me on twitter @rderik or subscribe to the newsletter. If you want to send me a direct message you can send it to [email protected].
Filename extension | .app, .framework, .kext, .plugin, .docset, .xpc, .qlgenerator, .component, .saver, .mdimporter, etc. |
---|---|
Uniform Type Identifier (UTI) | com.apple.bundle |
Container for | executable binary, metadata, other bundles, any other file needed to run the application. |
In NeXTSTEP, OPENSTEP, GNUstep, and their lineal descendants macOS and iOS, a bundle is a file directory with a defined structure and file extension, allowing related files to be grouped together as a conceptually single item.
Examples of bundles that contain executable code include applications, frameworks, and plugins. This kind of bundle usually contains one file representing executable code, and files that represent resources such as nibs, templates, images, sounds, and other media. On some other systems, such as Microsoft Windows, these resources are usually included directly in the executable file itself at compile time. On older Macintoshes, a similar technique is used, where additional metadata can be added to a file's resource fork. Similar in concept are the application directories used in RISC OS and on the ROX Desktop.
Examples of bundles that do not contain executable code include document packages (iWork documents) and media libraries (iPhoto Library).
Bundles are programmatically accessed with the
NSBundle
class in Cocoa, NeXTSTEP and GNUstep's Foundation frameworks, and with CFBundle
in Core Foundation. Bundles often include an Info.plist file for metadata.[1] The Uniform Type Identifier (UTI) for an Apple bundle is com.apple.bundle
.[2]Application bundles[edit]
Filename extension | |
---|---|
Uniform Type Identifier (UTI) | com.apple.application-bundle |
Type of format | application software |
Container for | executable binary |
Extended from | Bundle |
Application bundles are directory hierarchies, with the top-level directory having a name that ends with a
.app
extension. In an application bundle, the first directory in the bundle underneath the top-level directory is usually named Contents
. Within Contents
there is usually another directory (called MacOS
on Macs), which contains the application's executable code. Within the Contents
folder there is usually also a directory called Resources
, which contains the resources of the application. Among other things, the
Resources
folder contains localized versions of the application's nib files.Other common subdirectories include
Plugins
, Frameworks
, and Shared Frameworks
. The Frameworks
directory contains frameworks used by the application, and are used even if another version of the framework exists on the system. The Shared Frameworks
directory contains frameworks that can be used both by the application that contains them, and other applications; they are used only if a newer version does not exist elsewhere on the system. Plugins
contains extensible code used by the application.By default, the Finder displays application bundles, which can also be referred to as packages, as opaque files with no underlying structure; the contents of the bundle can be shown with the 'Show Package Contents' context menu item.
Macos App Bundle Structure Builder
GNUstep by default uses the name of the application to name the folder that contains application code. An alternative is to name them by the computer architecture and OS the code is intended for to form a fat binary, so the application can be opened on many platforms.[3][4]
macOS framework bundles[edit]
Filename extension | .framework |
---|---|
Uniform Type Identifier (UTI) | com.apple.framework |
Extended from | bundle |
macOS frameworks are also stored as bundles;[5] the top-level directory of a framework bundle has a name that is the name of the framework followed by the extension
.framework
. In the top-level directory is a Versions
directory, with subdirectories for one or more versions of the framework, each subdirectory containing the dynamic library code for the framework, in a file whose name is the same as the name of the framework, possibly with a Headers
folder containing header files for the framework, and other subfolders such as Resources
. The Versions
directory also contains a symbolic link Current
to the directory for the current version of the framework. In the top-level directory are symbolic links to the contents of Versions/Current
.[6]The Finder displays framework bundles as directories rather than as opaque files.
Although GNUstep uses frameworks, they are not usually stored as bundles. This is because the full semantics of framework loading are considered too alien to other platforms.[7]
Loadable bundles[edit]
Loadable bundles are bundles which contain code that can be loaded at runtime.[8] Loadable bundles usually have the extension
.bundle
, and are most often used as plug-ins. On macOS, there is a way to load bundles even into applications that do not support them, allowing for third party hacks for popular applications, such as Safari[9] and Apple Mail.[10][11] A feature inherited from NeXTSTEP, GNUstep has the -[NSBundle principalClass]
interface too.By default, the Finder displays loadable bundles, which can also be referred to as packages, as opaque files with no underlying structure; the contents of the bundle can be shown with the 'Show Package Contents' context menu item.
Other bundle formats[edit]
There are many third-party macOS applications which utilize their own custom bundle format (e.g. CandyBar
.iContainer
, Aperture.aplibrary
, VMware Fusion.vmwarevm
, etc.)..lproj[edit]
An .lproj file is a bundle that contains localization files for OpenStep, macOS, or GNUstep software. It typically contains the
.nib
files for a given language along with .strings
files and images if needed (for example, ReadMe or license files). These localized files are used by installer makers to customize install packages. They are also included in an application bundle.See also[edit]
- Application Directory — the RISC OS analogue to an application bundle
- AppImage — A Linux application that makes use of similar principles
References[edit]
Macos App Bundle Structure Finder
- ^'Information Property List - Bundle Resources'. Apple Developer Documentation.
- ^'System-Declared Uniform Type Identifiers'. Uniform Type Identifiers Reference. Apple Inc. Retrieved 2012-06-10.
- ^'PackagingDrafts/GNUstep'. Fedora Project Wiki.
- ^'gnustep/tools-make: README.Packaging'. GitHub.
- ^'Framework'. developer.apple.com. Retrieved 2020-10-06.
- ^'Anatomy of Framework Bundles'. Apple Inc. Retrieved 2011-09-03.
- ^'User FAQ'. GNUstep.
- ^Code Loading Programming Topics for Cocoa: About Loadable Bundles
- ^'Pimp My Safari: plugins'. Archived from the original on 2007-10-31.
- ^'Apple Mail plug-ins and tools'.
- ^'Hawk Wings — Plug-ins for Apple Mail'. Archived from the original on 2007-08-31.
External links[edit]
- Bundle Programming Guide at Apple Developer Connection
- NSBundle documentation from the GNUstep project
- Platypus — a tool to create application bundles around scripts
Macos App Bundle Structure Tutorial
Retrieved from 'https://en.wikipedia.org/w/index.php?title=Bundle_(macOS)&oldid=982117124'