• Stars
    star
    2,348
  • Rank 19,596 (Top 0.4 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created about 10 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Clean up your status bar for taking screenshots on the iOS simulator.

Simulator Status Magic

Modify the iOS Simulator so that it has a perfect status bar, then run your app and take perfect screenshots every time. The modifications made are designed to match the images you see on the Apple site and are as follows:

  • 9:41 AM is displayed for the time.
  • The battery is full and shows 100%.
  • 5 bars of cellular signal and full WiFi bars are displayed.
  • Tue Jan 9 is displayed for the date (iPad only)

Can't I just use xcrun simctl status_bar? πŸš€

Starting in Xcode 11, the simctl command line tool includes a status_bar option that allows you to override the appearance of the status bar in the simulator. Hopefully this will eventually supercede the need for SimulatorStatusMagic, but at the moment it still has holes that make this project continue to be relevant. In particular, simctl status_bar does not currently provide a way to add localized date and time strings in the status bar.

1) Using in screenshot automation UI Tests

import SimulatorStatusMagic

final class YourUITests: XCTestCase {

    override func setUpWithError() throws {
      SDStatusBarManager.sharedInstance().enableOverrides()
      // ... your other setup code
    }

    override func tearDownWithError() throws {
      SDStatusBarManager.sharedInstance().disableOverrides()
      // ... your other teardown code
    }

Because the package is only added to your UI test this has no effect on your app target.

Cocoapods/Carthage It is recommended to only include SDStatusBarManager in your debug configuration so that the code is never included in release builds. When you want to apply a perfect status bar, call [[SDStatusBarManager sharedInstance] enableOverrides]. To restore the standard status bar, call [[SDStatusBarManager sharedInstance] disableOverrides].

2) Using the demo app to enable/disable overrides

  • Clone this repository.
  • Open SimulatorStatusMagic.xcodeproj with Xcode 6 (or above).
  • Run the app target SimulatorStatusMagic (not SimulatorStatusMagiciOS) on whichever simulator type you would like to modify (it works with every device).
  • Once the app launches, press the only button on the screen :)
  • That's it, you're done! Now just run your app and take screenshots.

How do I remove the customisations?

Run the app again and click "Restore Default Status Bar". Resetting the iOS Simulator using the normal menu option also works.

What about automation of the sample app?

If you'd prefer to automate the app itself to automatically enable or disable the overrides, this can be done with environment variables.

Run with:

SIMULATOR_STATUS_MAGIC_OVERRIDES = enable

or

SIMULATOR_STATUS_MAGIC_OVERRIDES = disable

The overrides will be automatically enabled or disabled on launch.

Does this work on device?

No. The status bar server is blocked on devices. However, macOS includes the facility to include a perfect status bar when recording your device screen with QuickTime (Read more).

How does this work?

The best idea is to check the source code which should get you started with how it works :)

Updating for new versions of iOS

There's a general pattern for updating this project to support a new version of iOS, although this could change if Apple changes something in the future.

Prepare the new files.

  1. Copy the previous release's SDStatusBarOverriderPostXX_Y.{h,m} files, and update them to the new version.
  2. Update SDStatusBarManager.m to refer to the new overrider if detecting the new operating system version.

Find the updated structs in the runtime headers.

  1. Download the latest version of the dsdump tool.
  2. Run dsdump against the UIKitCore framework binary, to generate the private runtime headers.
./dsdump --objc -a x86_64 --verbose=5 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore --defined > ~/Desktop/UIKitCore.txt
  1. Find UIStatusBarServerListener in the output.

Update the structs in the new overrider.

There are two structs, StatusBarRawData and StatusBarOverrideData, that need to be updated. Each corresponds to a line in the runtime header output for UIStatusBarServerListener. It should be pretty easy to figure out the mapping if you study it for a minute.

  1. Update StatusBarRawData and StatusBarOverrideData to match any changes to the structs in the runtime headers.

Check if it works

That should be it!

  1. Run the sample app, and verify that the status bar is updated correctly.
  2. If anything new has been added to the status bar that needs to be adjusted, make additional changes to your new SDStatusBarOverrider.

Contributing

We'd love contributions! Found a bug? If you report it with a pull request attached then you get a gold star :)

However, the scope of this project is intentionally limited. We're not planning to add options to this to allow ultimate customisation of the status bar. It's intended to do just one job really well, change the status bar to match Apple's marketing materials.