# Shmoopi iOS System Services: one facade and one carrier table Apple emptied

> Shmoopi's iOS System Services folds hardware, network, battery, disk and memory lookups into a single read-only Objective-C singleton, which makes diagnostics cheap and data collection blunt. Its API reference is also an honest map of what an iOS app can no longer obtain, starting with carrier data.

**Shmoopi/iOS-System-Services** — iOS System Services is a class to gather all available information about a device.

- Repository: https://github.com/Shmoopi/iOS-System-Services
- Website: http://www.shmoopi.net/
- Stars: 1,996 · Forks: 363
- Language: Objective-C
- License: MIT
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/shmoopi-ios-system-services

## One singleton with seventy read-only properties

[SystemServices sharedServices] is the only entry point the README names, and every documented property hangs off it as `readonly`. One sentence lists what the library reaches for: hardware, network, battery, motion, disk, memory, processor, carrier, accessory, localization and application information. A first call is two lines, import the header and read one property.

```objective-c
// Import System Services
#import "SystemServices.h"

// Read a single value
NSLog(@"Device model: %@", [SystemServices sharedServices].deviceModel);

// Or grab everything at once
NSLog(@"All system information: %@", [SystemServices sharedServices].allSystemInformation);
```

The snapshot call in that sample deserves a second look before it goes into a shipping build. `allSystemInformation` hands back a dictionary of (almost) everything the library knows, so one log statement can drop device identity, network addresses and battery state into a crash report without any of it being enumerated by hand. Device identity arrives in four shapes: `deviceModel` gives `iPhone`, `systemsVersion` gives `18.0`, `systemDeviceTypeNotFormatted` gives a raw board string such as `iPhone17,1`, and `systemDeviceTypeFormatted` maps it to `iPhone 16 Pro`. That mapping table ages worst of anything in here, and coverage is claimed for the latest iPhone, iPad, iPod touch and Apple TV models.

## Three install routes and a folder with a space

Three routes are documented and none of them asks for a build setting. Under CocoaPods the dependency is a single line in the `Podfile`, followed by `pod install`.

```ruby
pod 'SystemServices', '~> 3.0'
```

That constraint pins the library to the 3.x line. Swift Package Manager takes the repository URL through the Add Package Dependencies menu in Xcode, or a line in `Package.swift`.

```swift
dependencies: [
    .package(url: "https://github.com/Shmoopi/iOS-System-Services.git", from: "3.0.0")
]
```

The manual route asks you to drag the `System Services` folder into the project. Watch the space in that folder name: the pod, the module and the header you import are all spelled without it, as `SystemServices` and `SystemServices.h`, so a manual install depends on getting the header onto the search path, and no instruction for that appears in the README. Swift callers get a note instead: `import SystemServices` for the package route, a bridging header for CocoaPods and manual installs, then `SystemServices.shared()`. Stated requirements are iOS 15.0+, Objective-C under ARC and Xcode 15+, and the frameworks the manual section names are `AVFoundation`, `CoreTelephony`, `CoreMotion`, `ExternalAccessory`, `Security`, `UIKit` and `Foundation`.

## Carrier fields Apple stopped filling in iOS 16

The carrier table is where the README contradicts its own pitch. Six properties are offered, from `carrierName` and `carrierCountry` through `carrierMobileCountryCode`, `carrierISOCountryCode`, `carrierMobileNetworkCode` and the `carrierAllowsVOIP` flag, sitting under a header that promises a drop-in library with no boilerplate and no setup. The note under that same table then records that Apple deprecated `CTCarrier` and stopped returning real carrier data to third-party apps in iOS 16, so those values degrade to nil or placeholders on modern systems. The manual install section, further up, still lists `CoreTelephony` as an ordinary part of the iOS SDK, which remains true of the framework and no longer true of what it hands back. Any feature keyed on MCC, MNC or ISO country codes has to survive empty strings from these getters, and a placeholder value is indistinguishable from a real one once it reaches a report.

## A jailbreak check typed int among BOOL flags

Read the Hardware table closely and one row breaks the pattern. Every neighbouring flag, including `multitaskingEnabled`, `proximitySensorEnabled`, `debuggerAttached`, `pluggedIn`, `stepCountingAvailable`, `distanceAvailable` and `floorCountingAvailable`, is typed `BOOL`, yet `jailbroken` is typed int and is described as non-`NOTJAIL` when the device appears jailbroken. A sentinel plus a magic constant is harder to consume than a boolean, and a caller has to compare against a named constant whose numeric value the README never prints. That same table also files `debuggerAttached` under hardware rather than under process, next to the motion sensor availability flags. For an app deciding how much to relax its own protections, these three rows matter most, and the README documents neither which paths get checked nor what a failed check hands back.

## A blocking public IP lookup behind a getter

The network category hides the sharpest edge in the whole API. `externalIPAddress` is documented as a public IP obtained by synchronous network call, which means an ordinary property read can block on the network, and no timeout, failure value or caching rule is written down anywhere. Read-only is not the same as cheap. The rest of the category is close to free: `currentIPAddress` reports the active interface, `connectedToWiFi` and `connectedToCellNetwork` are booleans, and the cellular and Wi-Fi rows expose address forms through `cellIPAddress`, `cellNetmaskAddress`, `cellBroadcastAddress`, `wiFiIPAddress`, `wiFiNetmaskAddress`, `wiFiBroadcastAddress` and `wiFiRouterAddress`. Eight properties for two interfaces, plus one property that reaches out to the internet from inside an accessor.

## Sentinels and a snapshot dictionary with no schema

`allSystemInformation` is described as a dictionary of (almost) everything in one call, and those parentheses carry the warning. No key list is given, so a consumer has to treat the dictionary as an unversioned bag rather than a contract. Several values inside it are sentinels rather than measurements. `batteryLevel` returns -1 when the battery cannot be read, the README's example being the Simulator, while `charging` and `fullyCharged` are plain booleans with no unavailable state at all. `systemsUptime` is a string formatted as `dd hh mm`, and no raw seconds value appears anywhere in the tables. Disk figures arrive twice, as human-readable strings in `diskSpace`, `freeDiskSpaceinRaw`, `freeDiskSpaceinPercent`, `usedDiskSpaceinRaw` and `usedDiskSpaceinPercent`, and as byte counts in `longDiskSpace` and `longFreeDiskSpace`. Memory has no equivalent raw column: `totalMemory` is a double in megabytes, and free, used, active and inactive memory each get a raw and a percent pair.

## What the facade hides from the SDK calls it wraps

The honest comparison is not with another library but with the framework calls underneath. Assembled by hand, the same screen is a scatter of small lookups across `AVFoundation`, `CoreTelephony`, `CoreMotion`, `ExternalAccessory`, `Security`, `UIKit` and `Foundation`, each with its own error path and its own formatting decision. SystemServices removes that scatter and adds three things you would otherwise write yourself: pre-rendered values such as `systemDeviceTypeFormatted` and `nameAttachedAccessories`, which the latter documents as comma-separated; the all-in-one dictionary; and a uniform `readonly` surface where mixed types sit next to each other. What it costs is visibility. Because every category is presented in the same tidy style, a value Apple no longer supplies looks exactly like a fresh one, and `processorsUsage` reporting per-core values as an `NSArray *` between 0.0 and 1.0 gives no hint about the sampling window behind it.

## A demo app and four screenshots, no test target

Two folders at the repository root hint at how this is meant to be used. `SystemServicesDemo/` is the demo app, and `Sample Images/` holds the four screenshots the README embeds for hardware, network, memory and disk. `Package.swift`, `SystemServices.podspec` and `CONTRIBUTING.md` sit beside them. No entry at that level is named for a test suite, apart from the `.github/` directory whose contents are not described. The library is MIT licensed and its last push is dated 2026-07-01. The documentation gap that matters for adoption sits elsewhere: no key list for `allSystemInformation`, no fallback behaviour for a refused motion or telephony call, and no statement of which categories are unavailable on a locked device. A surface this wide is cheap to adopt and hard to diff, since a new iOS version can change what a getter returns without touching its signature.

## Conclusion

iOS System Services suits support diagnostics and crash context, where one singleton beats the scattered framework lookups it hides, and fails carrier analytics, jailbreak policy work and any assumption that a getter is cheap. Verify three things first: whether the carrier rows still return values on the OS versions you ship, what `NOTJAIL` equals, and which keys `allSystemInformation` emits. A 70+ property surface is cheap to adopt and easy to leave stale, because nothing in the API says which rows a new iOS version empties. Read the carrier note and the int row beside the jailbreak flag before wiring either into a shipping build.

## FAQ

### How do I get a full device snapshot with iOS System Services?

Call `allSystemInformation` on the shared instance; the README says it returns a dictionary of (almost) everything in one call, and the parentheses are its own hedge. The keys are not listed, so treat the dictionary as an unversioned bag.

### What are the iOS and Xcode requirements for iOS System Services?

The requirements table lists iOS 15.0+, Objective-C under ARC and Xcode 15+. No older deployment target, tested device list or simulator matrix appears in the README.

### Why do the carrier properties return nil on a recent iOS in iOS System Services?

Apple deprecated `CTCarrier` in iOS 16 and stopped returning real carrier data to third-party apps, so `carrierName`, `carrierCountry` and the country code fields degrade to nil or placeholder values on modern systems. `carrierAllowsVOIP` is exposed the same way.

### What does the jailbroken property return in iOS System Services?

It is typed int rather than `BOOL`, and a value other than `NOTJAIL` means the device appears jailbroken. The README prints neither the numeric value behind `NOTJAIL` nor the paths that get checked.

### Is externalIPAddress safe to call on the main thread in iOS System Services?

The README documents it as a public IP fetched by synchronous network call, so a property read can block on the network. No timeout, failure value or caching rule is given.

### How do I add iOS System Services to a Swift project?

Add the repository URL through the Add Package Dependencies menu in Xcode, or add `from: "3.0.0"` to `Package.swift`, then call `SystemServices.shared()`. CocoaPods and manual installs need `#import "SystemServices.h"` in a bridging header instead.

## Sources

- [Issues](https://github.com/Shmoopi/iOS-System-Services/issues)
- [License: MIT](https://github.com/Shmoopi/iOS-System-Services/blob/master/LICENSE)
- [Project website](http://www.shmoopi.net/)
- [README](https://github.com/Shmoopi/iOS-System-Services/blob/master/README.md)
- [Shmoopi/iOS-System-Services on GitHub](https://github.com/Shmoopi/iOS-System-Services)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shmoopi-ios-system-services
