An open API service indexing awesome lists of open source software.

https://github.com/yusukehosonuma/swiftui-simulator

:iphone: Simulate device configurations in real-time. (and useful tools for development)
https://github.com/yusukehosonuma/swiftui-simulator

ios simulator swift swiftui

Last synced: 8 months ago
JSON representation

:iphone: Simulate device configurations in real-time. (and useful tools for development)

Awesome Lists containing this project

README

          

# SwiftUI-Simulator

Simulate device configurations in real-time. (and useful tools for development)

https://user-images.githubusercontent.com/2990285/163325330-13297947-7222-4cf7-a80b-d999094546d9.mov

## Feature

### Simulation

- [x] Any device screen
- [x] Light/Dark mode
- [x] Locale
- [x] Calendar
- [x] TimeZone
- [x] Dynamic Type Sizes (iOS 15+)
- [x] Rotate
- [ ] ~~Legibility Weight (Not working in latest iOS and Xcode preview)~~

**Note: This is only a simulation and may differ from how it looks on a simulator or real device.**

### UserDefaults browser

You can browse and edit `UserDefaults`.

| Browse | Edit (as JSON) | Edit (Date) | Export |
| -- | -- | -- | -- |
|image|image|image|image|

Supported types:

- Property list types
- [x] `String`
- [x] `Bool`
- [x] `Int`
- [x] `Float`
- [x] `Double`
- [x] `URL`
- [x] `Date`
- [x] `[Any]`
- [x] `[String: Any]`
- JSON encoded types
- [x] `Data`
- [x] `String`

The AppGroup (`UserDefaults(suiteName: "xxx")`) was supported, please see [Configurations](#Configurations).

## Quick Start

1. Install via Swift Package Manager.

```swift
let package = Package(
dependencies: [
.package(url: "https://github.com/YusukeHosonuma/SwiftUI-Simulator.git", from: "1.6.0"),
],
targets: [
.target(name: "", dependencies: [
.product(name: "SwiftUISimulator", package: "SwiftUI-Simulator"),
]),
]
)
```

2. Surround the your app's root view with `SimulatorView`.

```swift
#if DEBUG
import SwiftUISimulator
#endif

@main
struct ExampleApp: App {
var body: some Scene {
WindowGroup {
#if DEBUG
SimulatorView { // ✅ Please surround the your app's root view with `SimulatorView`.
ContentView()
}
#else
ContentView()
#endif
}
}
}
```

3. Launch on any simulator or device. (Large screen is recommended)

| iPhone 13 Pro Max | iPad Pro (12.9-inch) |
|--|--|
|image|image|

## Requirements

- iOS 14+ (iPhone / iPad)
- `Dynamic Type Sizes` is supports in iOS 15+

## Limitation

- This OSS supports **SwiftUI app** only.

- For example, it may not work if you have resolve `locale` by yourself. (e.g. use [SwiftGen](https://github.com/SwiftGen/SwiftGen))
- `sheet()` and `fullScreenCover()` are not working currently. [#37](https://github.com/YusukeHosonuma/SwiftUI-Simulator/issues/37)

## Custom Debug Menu

You can add custom debug menu.

```swift
SimulatorView {
// 💡 Add custom debug menu.
Button {
print("Hello!")
} label: {
Label("Custom Debug", systemImage: "ant.circle")
}
} content: {
ContentView()
}
```

This makes it easy to run custom debug action.

image

## Built-in Modifier (Experimental)

As a built-in, we provide a modifier that displays the file name of the View.

| Debug enabled | Debug disabled |
| -- | -- |
| image | image |

The installation procedure is as follows. (recommended)

1. Add `View+Debug.swift`.

```swift
import SwiftUI

#if DEBUG
import SwiftUISimulator
#endif

public extension View {
func debugFilename(_ file: StaticString = #file) -> some View {
// ✅ Enabled when debug build only.
#if DEBUG
simulatorDebugFilename(file) // 💡 or any `String`.
#else
self
#endif
}
}
```

2. Add custom debug menu and environment.

```swift
struct ExampleApp: App {
//
// ✅ To show/hide
//
#if DEBUG
@State private var isEnabledDebugFilename = false
#endif

var body: some Scene {
WindowGroup {
#if DEBUG
SimulatorView {
//
// ✅ Add debug menu.
//
Menu {
Toggle(isOn: $isEnabledDebugFilename) {
Label("Filename", systemImage: "doc.text.magnifyingglass")
}
} label: {
Label("Debug", systemImage: "ant.circle")
}
} content: {
RootView()
//
// ✅ Add `simulatorDebugFilename` environment value to root view.
//
.environment(\.simulatorDebugFilename, isEnabledDebugFilename)
}
#else
ContentView()
#endif
}
}
}
```

3. Add `debugFilename()` modifier to any views. (where you needed)

```swift
struct FooView: View {
var body: some View {
Text("Foo")
.debugFilename() // ✅
}
}
```

Note:
As you can probably imagine, it is easy to make this yourself.
Please refer to [DebugFilenameModifier.swift)](https://github.com/YusukeHosonuma/SwiftUI-Simulator/blob/main/Sources/SwiftUISimulator/DebugFilenameModifier.swift).

## Configurations

You can specify default `devices`, `locale identifiers`, `calendar identifiers` and `timezone`.

```swift
SimulatorView(
defaultDevices: [.iPhone11, .iPhone13ProMax], // Set
defaultLocaleIdentifiers: ["it", "fr"], // Set
defaultCalendarIdentifiers: [.gregorian, .iso8601], // Set
defaultTimeZones: [.europeParis, .europeBerlin], // Set
accentColorName: "MyAccentColor", // when not use default accent color name in Assets.
userDefaultsSuiteNames: ["someDomain"] // [String]
) {
RootView()
}
```
This is useful if you want to share with your team.

## Contributions

Issues and PRs are welcome, even for minor improvements and corrections.

## FAQ

Q. How it works?

A. Perhaps as you might imagine, this is achieved by overriding SwiftUI's [Environment](https://developer.apple.com/documentation/swiftui/environment).

Q. How to disable this simulator?

A. `Disable Simulator` in setting menu.

image

## Author

Yusuke Hosonuma / [@tobi462](https://twitter.com/tobi462)