# MMWormhole: File-Based Messaging Between iOS Apps and Extensions

> MMWormhole bridges an iOS or OS X app and its extensions by archiving messages to shared App Group files. It is a simple, mature Objective-C library with a clear trade-off: near-instant updates require Darwin notifications, and background delivery is not guaranteed.

**griddynamics-archive/MMWormhole** — GitHub describes it as Message passing between iOS apps and extensions.. The repository metadata lists Objective-C as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

- Repository: https://github.com/griddynamics-archive/MMWormhole
- Stars: 3,929 · Forks: 319
- Language: Objective-C
- License: MIT
- Published: 2026-08-13 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/griddynamics-archive-mmwormhole

## The Problem: Extensions Cannot Talk to Their App Directly

iOS extensions, such as Today widgets or Watch apps, run in separate processes from their containing app. Apple provides no true interprocess communication between them. MMWormhole solves this by creating a shared mailbox system based on files. The library archives messages to a directory inside the app group that both the app and the extension can access. This lets you pass commands or small data objects back and forth. The intended audience is any developer building an extension that needs to reflect state from the main app, or vice versa. The README explicitly states that the effect resembles interprocess communication, but it is not the real thing. That distinction matters for anyone expecting zero-latency or guaranteed delivery.

## The Mechanism: Archived Files and Darwin Notifications

MMWormhole uses NSKeyedArchiver to serialize message objects into files written to the shared App Group. Each message has an identifier, which acts like a unique mailbox name. When you pass a message, the object is archived to a file named after that identifier. To read it, you can either poll for the message with messageWithIdentifier: or set up a listener. The listener relies on CFNotificationCenter Darwin Notifications to notify interested parties when a message is updated. This gives near-instant updates when both sides are awake. The README compares the system to a collection of shared mailboxes: you know where a message goes, but not when it will be picked up. The key constraint is that notifications only trigger in the containing app if the app is awake in the background. If the app is suspended or terminated, messages wait in the file until the app wakes up.

## Getting Started: App Groups, CocoaPods, and Initialization

To use MMWormhole, you first configure your app and extension to support App Groups in Xcode. Then you install the library via CocoaPods with pod 'MMWormhole', '~> 2.0.0' or via Carthage. The README notes that the example app only works with your own App Group identifiers and entitlements. Initialization is straightforward. In Objective-C you write: [[MMWormhole alloc] initWithApplicationGroupIdentifier:@"group.com.mutualmobile.wormhole" optionalDirectory:@"wormhole"]. In Swift it is MMWormhole(applicationGroupIdentifier: "group.com.mutualmobile.wormhole", optionalDirectory: "wormhole"). The optional directory keeps wormhole files separate from other App Group content. Passing a message is one line: passMessageObject:identifier:. Reading is either a synchronous fetch or a listener block. The README gives a concrete example where a button number is passed and the listener updates a label.

## Designing a Communication Scheme: Identifiers as Endpoints

The README advises treating message identifiers like web service endpoints. You should design clear, semantic identifiers so that reading code reveals who sent a message and why. This is more than style advice; it affects how you handle missing messages. Since delivery is not guaranteed immediately, you should check the mailbox when your app or extension wakes up. The README suggests this as a good practice. The identifier scheme also matters for WatchConnectivity support. MMWormhole includes a singleton subclass, MMWormholeSession, that wraps Apple's WatchConnectivity framework. The README emphasizes that this support is not a replacement for WatchConnectivity, and you must carefully consider where MMWormhole fits in your watch app's communication system. That is a honest limitation: the library offers a convenience layer, not a full solution.

## Limitations: Background Delivery and File Size

The most significant limitation is that notifications are not delivered when the containing app is not awake. If the app is in the background but suspended, Darwin notifications may not fire. The README states that notifications will only be triggered if the app is awake in the background. That makes MMWormhole ideal for cases where the app is already running via background modes, such as audio or location. It is not suitable for waking the app to process a message. Another constraint is that messages are archived files, so they are not real-time IPC. The README also notes that while larger structures like a Core Data database can be shared via App Groups, MMWormhole is designed for its own directory and basic messages. Trying to push large data through it would be inefficient and contrary to its purpose.

## Alternatives: WatchConnectivity and Direct App Group File Sharing

The README itself points to WatchConnectivity as the alternative for watchOS 2. Apple's framework provides a more robust and real-time channel for watch apps, with background transfer and userInfo dictionaries. MMWormhole's MMWormholeSession is a thin wrapper over that, so if you need reliable background delivery, you should use WatchConnectivity directly. Another alternative is to bypass MMWormhole and write your own file-based communication using App Group directories and NSFileCoordinator. That gives you full control over file naming, conflict resolution, and cleanup, but you lose the listener mechanism and the convenience of NSCoding serialization. The trade-off is between simplicity and control. MMWormhole is simpler, but it is also a fixed design that you cannot extend beyond what the API offers.

## Maintenance and License: A 2017 Snapshot

The repository has not been pushed since May 2017, and the latest release is 2.0.1 from that date. There is no homepage and the default branch is master. The project is archived? No, the archive flag is false, but the last push is over seven years old. That means you should treat it as a stable, frozen library. It is written in Objective-C, which still works in modern iOS projects, but you will need to verify that it compiles with current SDKs. The MIT license is permissive, allowing commercial use and modification, but it comes with no warranty. You should check the license file for exact terms. For maintenance, you are on your own: there is no active upstream to fix bugs or add support for new iOS features. If you adopt it, you are committing to maintaining it yourself or accepting that it will not evolve.

## Conclusion

Adopt MMWormhole if you need a lightweight, well-understood way to pass small NSCoding-compliant objects between an iOS app and its widget, watch, or other extension, and you can live with file-based semantics and no guaranteed background delivery. Do not use it for large data, real-time requirements, or when your app is not expected to be awake, since notifications only fire when the app is running in the background. Before adopting, verify that your App Group entitlements are correctly configured on both sides, and check that the last push from 2017 still compiles with your current Xcode and iOS SDK, since the project has not been updated since then.

## FAQ

### What is MMWormhole used for?

It bridges an iOS or OS X extension and its containing application so the two can pass data and commands. Messages are serialized with NSKeyedArchiver, archived to files in a shared App Group, and announced with CFNotificationCenter Darwin notifications so the other side can react quickly when it is running.

### Does MMWormhole use interprocess communication?

No. The README states that true interprocess communication does not exist between extensions and containing apps, and that MMWormhole only resembles it: messages are archive files written into a directory inside the shared App Group, with a Darwin notification as a fast path when the receiver is awake.

### What can I send through MMWormhole?

Any object that is NSCoding compliant, because the library serializes messages with NSKeyedArchiver. For most apps the README considers simple strings, numbers or JSON objects enough to drive the interface of a widget or an Apple Watch app.

### Will MMWormhole deliver a message while my app is suspended?

The file will be waiting, but the notification will not. Notifications are only triggered in the containing app if it is awake in the background, which is why the README recommends checking the mailbox for that identifier whenever the app or extension wakes up.

### How do I install MMWormhole?

Three ways: CocoaPods with pod 'MMWormhole', '~> 2.0.0', Carthage, or by downloading the source files. Either way the app and its extensions must be configured to support shared App Groups first, since that group is where the archive files are written.

## Sources

- [Official README](https://github.com/griddynamics-archive/MMWormhole#readme)
- [Project repository](https://github.com/griddynamics-archive/MMWormhole)
- [Release notes](https://github.com/griddynamics-archive/MMWormhole/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/griddynamics-archive-mmwormhole
