Skip to content

Commit

Permalink
macOS support (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahsmartin authored Dec 12, 2023
1 parent 053b24b commit 76ee50e
Show file tree
Hide file tree
Showing 24 changed files with 151 additions and 41 deletions.
7 changes: 7 additions & 0 deletions .spi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 1
builder:
configs:
- platform: ios
scheme: PreviewGallery
- platform: macos
scheme: PreviewGallery
8 changes: 6 additions & 2 deletions DemoApp/DemoApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
FA4F5ADA2A7A3E7700B268FF /* Snapshotting in Embed Frameworks */ = {isa = PBXBuildFile; productRef = FA4F5AD82A7A3E7700B268FF /* Snapshotting */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
FA5E82972A96448A008DE3F0 /* StateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA5E82962A96448A008DE3F0 /* StateView.swift */; };
FA9C8E442A56959300DC4574 /* RatingPreviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9C8E432A56959300DC4574 /* RatingPreviews.swift */; };
FAA4F4CF2B271D9C00127B63 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA4F4CE2B271D9C00127B63 /* Color.swift */; };
FABCCD932AC39081008F4D3A /* EMGTestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FABCCD922AC39081008F4D3A /* EMGTestHandler.swift */; };
FACA23792A55FBEE0080545A /* DemoModule.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA1671D72A5399F700A42DB0 /* DemoModule.framework */; };
FAD0107B2AA29ABA007D1AF6 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD0107A2AA29ABA007D1AF6 /* TextView.swift */; };
Expand Down Expand Up @@ -117,6 +118,7 @@
FA44246E2AAA5B27005BFCD9 /* DemoApp.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = DemoApp.xctestplan; sourceTree = "<group>"; };
FA5E82962A96448A008DE3F0 /* StateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateView.swift; sourceTree = "<group>"; };
FA9C8E432A56959300DC4574 /* RatingPreviews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingPreviews.swift; sourceTree = "<group>"; };
FAA4F4CE2B271D9C00127B63 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
FABCCD922AC39081008F4D3A /* EMGTestHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EMGTestHandler.swift; sourceTree = "<group>"; };
FAC167E72A5F41C500D79C23 /* DemoAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
FACA23752A55FB970080545A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
Expand Down Expand Up @@ -208,6 +210,7 @@
children = (
FA1671D92A5399F700A42DB0 /* DemoModule.h */,
FA1671E32A539A0500A42DB0 /* RowView.swift */,
FAA4F4CE2B271D9C00127B63 /* Color.swift */,
FA1671E72A539EA900A42DB0 /* ProductCard.swift */,
FA1671E52A539CCF00A42DB0 /* ButtonView.swift */,
FA1671E92A539F6E00A42DB0 /* RatingView.swift */,
Expand Down Expand Up @@ -438,6 +441,7 @@
FA9C8E442A56959300DC4574 /* RatingPreviews.swift in Sources */,
FA1671E42A539A0500A42DB0 /* RowView.swift in Sources */,
FA1671E82A539EA900A42DB0 /* ProductCard.swift in Sources */,
FAA4F4CF2B271D9C00127B63 /* Color.swift in Sources */,
FA1671FB2A53E03800A42DB0 /* MessageRow.swift in Sources */,
FA1671FF2A53E1AF00A42DB0 /* ConversationMessageView.swift in Sources */,
FA1671FD2A53E11E00A42DB0 /* MessageView.swift in Sources */,
Expand Down Expand Up @@ -619,7 +623,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.emerge.PreviewsDemoApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down Expand Up @@ -660,7 +664,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.emerge.PreviewsDemoApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
2 changes: 1 addition & 1 deletion DemoApp/DemoApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import PreviewGallery

struct ContentView: View {
var body: some View {
NavigationView {
NavigationStack {
VStack {
NavigationLink("Open Gallery") {
LazyView(PreviewGallery())
Expand Down
2 changes: 2 additions & 0 deletions DemoApp/DemoApp/TestViews/RideDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ struct RideDetailView: View {
}
.padding()
}
#if os(iOS)
.navigationBarTitle(ride.name, displayMode: .inline)
#endif
}
}

Expand Down
9 changes: 5 additions & 4 deletions DemoApp/DemoApp/TestViews/RideOptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import SwiftUI
import DemoModule

struct RideOptionView: View {
var title: String
Expand All @@ -19,23 +20,23 @@ struct RideOptionView: View {
.font(.headline)

Text(description)
.foregroundColor(Color(uiColor: UIColor.systemGray))
.foregroundColor(Color(PlatformColor.systemGray))
.font(.subheadline)
.fixedSize(horizontal: false, vertical: true)
.lineLimit(2)

Text("$\(price, specifier: "%.2f")")
.font(.headline)
.foregroundColor(Color(uiColor: UIColor.systemBlue))
.foregroundColor(Color(PlatformColor.systemBlue))
}

Spacer()

Image(systemName: "chevron.right")
.foregroundColor(Color(uiColor: UIColor.systemGray))
.foregroundColor(Color(PlatformColor.systemGray))
}
.padding()
.background(Color(uiColor: UIColor.systemBackground))
.background(Color(PlatformColor.systemBackground))
.cornerRadius(12)
.shadow(color: .gray, radius: 3, x: 0, y: 2)
}
Expand Down
5 changes: 3 additions & 2 deletions DemoApp/DemoApp/TestViews/RideShareButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import SwiftUI
import DemoModule

struct RideShareButtonView: View {
var title: String
Expand All @@ -15,10 +16,10 @@ struct RideShareButtonView: View {
Button(action: action) {
Text(title)
.font(.headline)
.foregroundColor(Color(UIColor.systemBackground))
.foregroundColor(Color(PlatformColor.systemBackground))
.padding()
.frame(maxWidth: .infinity)
.background(Color(UIColor.label))
.background(Color(PlatformColor.label))
.cornerRadius(12)
}
.buttonStyle(PlainButtonStyle())
Expand Down
2 changes: 2 additions & 0 deletions DemoApp/DemoApp/TestViews/TextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Noah Martin on 9/1/23.
//

#if canImport(UIKit)
import Foundation
import SwiftUI

Expand All @@ -23,3 +24,4 @@ struct TextView_Previews: PreviewProvider {
TextView()
}
}
#endif
3 changes: 3 additions & 0 deletions DemoApp/DemoApp/TestViews/UIViewPreviews.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by Noah Martin on 10/9/23.
//

#if canImport(UIKit)
import Foundation
import UIKit

Expand All @@ -30,3 +31,5 @@ class TestViewController: UIViewController {
#Preview(body: {
return TestViewController() as UIViewController
})

#endif
26 changes: 26 additions & 0 deletions DemoApp/DemoModule/Color.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Color.swift
// DemoModule
//
// Created by Noah Martin on 12/11/23.
//

import Foundation

#if canImport(UIKit)
public typealias PlatformColor = UIColor
#else
import AppKit

public typealias PlatformColor = NSColor

extension NSColor {
public static var systemBackground: NSColor {
NSColor.windowBackgroundColor
}

public static var label: NSColor {
NSColor.labelColor
}
}
#endif
2 changes: 1 addition & 1 deletion DemoApp/DemoModule/ProductCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct ProductCardView: View {
.foregroundColor(.secondary)
}
.padding()
.background(Color(UIColor.systemBackground))
.background(Color(PlatformColor.systemBackground))
.cornerRadius(10)
.shadow(color: .secondary, radius: 3, x: 0, y: 2)
}
Expand Down
2 changes: 1 addition & 1 deletion DemoApp/DemoModule/RatingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct RatingView: View {
HStack(spacing: 4) {
ForEach(0..<5) { index in
Image(systemName: rating >= Double(index + 1) ? "star.fill" : "star")
.foregroundColor(Color(UIColor.systemYellow))
.foregroundColor(Color(PlatformColor.systemYellow))
.font(.body)
}
}
Expand Down
2 changes: 1 addition & 1 deletion DemoApp/DemoModule/RowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public struct RowView: View {
HStack(spacing: 4) {
ForEach(0..<5) { index in
Image(systemName: ratings >= Double(index + 1) ? "star.fill" : "star")
.foregroundColor(Color(UIColor.systemYellow))
.foregroundColor(Color(PlatformColor.systemYellow))
.font(.caption)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription

let package = Package(
name: "SnapshotPreviews",
platforms: [.iOS(.v15)],
platforms: [.iOS(.v15), .macOS(.v12)],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import PreviewGallery
NavigationLink("Open Gallery") { PreviewGallery() }
```

The gallery also supports macOS. However, snapshotting does not support macOS.

## Local Debugging

Use this Swift Package for locally debugging your views snapshots. You’ll need a UI test target that imports the `SnapshottingTests` and `Snapshotting` products from this package. Create a test that inherits from `PreviewTest` like this:
Expand Down
34 changes: 34 additions & 0 deletions Sources/PreviewGallery/Colors.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Colors.swift
//
//
// Created by Noah Martin on 12/11/23.
//

import Foundation

#if canImport(UIKit)
typealias PlatformColor = UIColor
#else
import AppKit

typealias PlatformColor = NSColor

extension NSColor {
static var label: NSColor {
NSColor.labelColor
}

static var secondaryLabel: NSColor {
NSColor.secondaryLabelColor
}

static var secondarySystemGroupedBackground: NSColor {
NSColor.controlBackgroundColor
}

static var systemGroupedBackground: NSColor {
NSColor.windowBackgroundColor
}
}
#endif
8 changes: 5 additions & 3 deletions Sources/PreviewGallery/ModulePreviews.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,22 @@ struct ModulePreviews: View {
title: "Screens",
subtitle: "\(featureProviders.count) Preview\(featureProviders.count != 1 ? "s" : "")")
.padding(16)
.background(Color(uiColor: UIColor.secondarySystemGroupedBackground))
.background(Color(PlatformColor.secondarySystemGroupedBackground))
}
}
ForEach(componentProviders) { preview in
NavigationLink(destination: PreviewsDetail(previewType: preview)) {
PreviewCellView(preview: preview)
.background(Color(uiColor: UIColor.secondarySystemGroupedBackground))
.background(Color(PlatformColor.secondarySystemGroupedBackground))
.allowsHitTesting(false)
}
#if canImport(UIKit)
.frame(width: UIScreen.main.bounds.width)
#endif
}
}
}
.background(Color(uiColor: UIColor.systemGroupedBackground))
.background(Color(PlatformColor.systemGroupedBackground))
.navigationTitle(module)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/PreviewGallery/ModuleScreens.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ struct ModuleScreens: View {
VStack(alignment: .leading) {
Text(provider.displayName)
.font(.headline)
.foregroundStyle(Color(UIColor.label))
.foregroundStyle(Color(PlatformColor.label))
.padding(.leading, 8)

Text("\(featurePreviews.count) Preview\(featurePreviews.count != 1 ? "s" : "")")
.font(.subheadline)
.foregroundStyle(Color(UIColor.secondaryLabel))
.foregroundStyle(Color(PlatformColor.secondaryLabel))
.padding(.leading, 8)
}
}
Expand Down
9 changes: 9 additions & 0 deletions Sources/PreviewGallery/PreviewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,20 @@ private extension Color {
static let slate100 = Color(#colorLiteral(red: 0.9450980392, green: 0.9607843137, blue: 0.9764705882, alpha: 1))

static let dynamicBackground = {
#if canImport(UIKit)
Color(UIColor { traitCollection in
if traitCollection.userInterfaceStyle == .dark {
return UIColor(Color.black)
}
return UIColor(Color.slate100)
})
#else
Color(NSColor(name: nil, dynamicProvider: { appearance in
if appearance.bestMatch(from: [.aqua, .darkAqua]) == .darkAqua {
return NSColor(Color.black)
}
return NSColor(Color.slate100)
}))
#endif
}()
}
8 changes: 5 additions & 3 deletions Sources/PreviewGallery/PreviewsDetail.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ struct PreviewsDetail: View {
VStack(alignment: .center) {
Text(preview.displayName ?? "Preview")
.font(.headline)
.foregroundStyle(Color(UIColor.label))
.foregroundStyle(Color(PlatformColor.label))
PreviewCell(preview: preview)
}
.padding(.vertical, 16)
#if canImport(UIKit)
.frame(width: UIScreen.main.bounds.width)
.background(Color(uiColor: UIColor.secondarySystemGroupedBackground))
#endif
.background(Color(PlatformColor.secondarySystemGroupedBackground))
}
}
}
.background(Color(uiColor: UIColor.systemGroupedBackground))
.background(Color(PlatformColor.systemGroupedBackground))
.navigationTitle(previewType.displayName)
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/SnapshotPreviewsCore/ConformanceLookup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public func getPreviewTypes() -> [LookupResult] {
for i in 0..<images {
let imageName = String(cString: _dyld_get_image_name(i))
// System frameworks on the simulator are in Xcode.app/Contents/** (Although Xcode could be renamed like Xcode-beta.app so don't check for that specifically)
guard !imageName.contains(".simruntime") && !imageName.contains(".app/Contents/") && !imageName.starts(with: "/usr/lib/") else {
guard !imageName.contains(".simruntime") && !imageName.contains(".app/Contents/Developer") && !imageName.starts(with: "/usr/lib/") else {
continue
}

Expand Down
Loading

0 comments on commit 76ee50e

Please sign in to comment.