Giter Site home page Giter Site logo

aspirinshot's Introduction

AspirinShot

Create your App Store screenshots in SwiftUI:

  • 🛠️ in Xcode
  • ✌️ using your #SwiftUI and #UIKit views
  • 🙅 no UITests
  • 🌐 Localized with Strings.file
  • 🌗 Light/Dark modes out-of-the-box
  • ⚡️ Ready-made templates
  • … and much more to come!
Browsing the gallery of screenshots PNG output

AspirinShot is free while it is in beta, you can take all the time you need to create your screenshots with it. Once you're ready to export your screenshots without watermark, please shoot me an email to get a free license.

🚧 Beta Warning: The documentation is incomplete. Please bear with me while I update this page and the code documentation. 😅

Contact:

I may build a gallery of "Made with AspirinShot" screenshots, so if you want to have your app featured, contact me!

Overview

The general idea is to use your app Views to compose your screenshots. You can provide these views custom data & environment objects, as well as ad-hoc assets. You will wrap your views in device bezels to make them look like screenshots, add text around, add subviews to zoom in on features, etc. Everything can be localized using .strings files.

The framework comes with a rich set of Environment variables (eg: ScreenshotFormat), Views (eg: ScreenshotView), ViewModifiers (eg: ProductBezelModifier) and Views for Previews (eg: ScreenshotPreviews) to help you design screenshots that look perfect in every size.

It also includes the most recent & commonly used product bezels, with all the pixels and points calculations already done for you.

🚀 Getting Started

  • Add the package to Xcode:
    • File > Add Packages…
    • Enter https://github.com/goodwhale/AspirinShot
    • Select your Target and make sure it's added to the Frameworks, Libraries, and Embedded Content
  • Create your screenshots, either:
    • Check the Starter Kit in this repo. You can copy/paste it in your project and start from there, it features a variety of screenshots.
    • or, Create one file per screenshot using the template below.
    • Prefer Selectable mode when previewing your screenshots as it will adjust the view to the display/output size. It's an option at the bottom left of the preview panel:
    CleanShot 2023-09-08 at 10 31 56@2x
#if DEBUG
import SwiftUI
import AspirinShot

extension Screenshot {
    static let first = Screenshot("First Screenshot")
}

struct FirstScreenshotView: View {
    // A lot is done for you automatically based on this, but you can access it
    // to adjust your design based on its `.platform` (iPhone, iPad…) or `.displaySize` or `.orientation`
    @Environment(\.screenshotFormat) private var screenshotFormat
    
    var body: some View {
        // Check the StarterKit for more templates
        // Play with .fit/.fill:
        // * .fill for a zoomed in effect, partial view
        // * .fit to see the entire view
        ScreenshotWithTitleView(position: .top(0.2), screenshot: .fit(0.95, .top)) {
            Rectangle()
                .foregroundStyle(.white)
                .overlay {
                    VStack {
                        Text("Hello", tableName: "AspirinShot")
                        Text("@AspirinShot")
                            .bold()
                    }
                    .font(.largeTitle)
                }
                // Play with .fit/.fill: the best option depends on the device and its screen format
                .productBezel(scaledTo: .fit, statusBar: .black(on: .white))
        } title: {
            AutoResizableText("**You will love\nthis app**")
                .multilineTextAlignment(.center)
                .padding()
                .padding(.horizontal)
        } background: {
            // Use a gradient or a pattern
            SFPatternView(systemName: "star.fill", itemSize: 40)
                .foregroundStyle(.teal)
        }
        // Set environment values
        .environment(\.managedObjectContext, PersistenceController.screenshots.viewContext)
        .environment(\.isProUser, true)
        .environmentObject(ViewModel())
    }
    
    private var contentView: some View {
        Rectangle()
            .foregroundStyle(Color.white)
    }
}

struct FirstScreenshotView_Previews: PreviewProvider {
    static var previews: some View {
        ScreenshotPreviews(.first, in: "fr") {
            FirstScreenshotView()
        }
    }
}
#endif

📚 For more details, helpers and templates to design your screenshots, see Designing your screenshots.

  • Preview and Export your screenshots
    • Create a file that will launch the global previewer/exporter
#if DEBUG
import SwiftUI
import AspirinShot

struct ScreenshotsASApp_Previews: PreviewProvider {
    static var previews: some View {
        AspirinShotPreview(
            screenshots: [.hero, .why, .how, .success], // All your `Screenshot` declarations
            userID: "yourUserId" // Only for export Ask me for a free access during beta
        ) { screenshot in
            switch screenshot { // Match each one to their view
                case .hero: HeroScreenshotView()
                case .why: WhyScreenshotView()
                case .how: HowScreenshotView()
                case .success: SuccessScreenshotView()
                default: EmptyView()
            }
        }
    }
}
#endif
  • Launch the preview in Live mode and export your screenshots.

📚 For more ways to preview your screenshots, see Previewing your screenshots

For more details about building and previewing your screenshots, make sure you visit the wiki. And you can start a discussion if you have any questions!

Known limitations

There are certain limitations for technical reasons, and because the project is still in its infancy.

Check out the know limitations and their workarounds.

Origin Story

Back in 2022, as I transitioned from UIKit to SwiftUI, I made sure my iPhone app would also look good on an iPad.

But I never enabled the iPad, because I didn't want to do the screenshots in all sizes and languages… That's how much I hated the process.

I started dreaming about using SwiftUI to create my screenshots, but none of the solutions I found worked for me. Especially because I wanted to be able to compose views and not just take a screenshot and frame it.

I tried a couple times do to it, but I kept hitting roadblocks, until one day it worked.

What I avoided doing for a year for my own applications, I've started doing for strangers because the process has become so simple and familiar. That's AspirinShot.

Why is it named AspirinShot?

It's a painkiller, and for App Store Screenshots.

App Store Screenshot > AS shot > AspirinShot


Copyright 2023 Goodwhale, EURL. All rights reserved.

aspirinshot's People

Contributors

sowenjub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

aspirinshot's Issues

Will this work with LocalizedStringResource aka String Catalogs support?

Hey, I'm using String Catalogs in a bit different way:
I have a swift class with strings:

static let ok = LocalizedStringResource("Ok", table: "General")

Then I'm using It like:

Text(String(localized:ok))

So all my SwiftUI view will use a lot such strings keys.
Now I Xcode Preview I can easily change language by just manage scheme, app language -> de for example.
And so all strings will update.. in any Preview.

Invalid semantic version not accepted by SPM

If you want feedback in another channel please let me know. I tried to use it the first time. My app is modularized with SPM meaning there's almost no code in the app target. I'd instead add a module to my app "ScreenshotsFeature", which depends on AspirinShot.

But now my Package.swift won't resolve due to:

Invalid semantic version string '0.9'

In general SPM packages should use only semantic versioning as far as I know.

As a workaround I added branch: "main" as version. This also failed:

Bildschirmfoto 2023-09-08 um 09 14 56

But that was maybe some Xcode issue. I had to resolve dependencies again.

A simple example project?

Hey, I just tried to add some you classes and some of them are not working.. I'm spending time you know.. dealing with...

I'm just expecting if something is PAID, it should just work and have a good examples which I can just open run and see the result with 0 effort.

Also, examples with String Catalogs would be good too.

LocalizedStringKey to String translations does not work

I use the following extensions to parse the LocalizedStringKey to a string. (Found this online). This works if I change the app language but does not work when exporting the screenshots in the different languages. At the places where I can use the LocalizedStringKey everything works as expected.

I am using SwiftUI to develop the app.
Is there any way to fix this?

The extensions I use (source: https://stackoverflow.com/questions/60841915/how-to-change-localizedstringkey-to-string-in-swiftui):

extension LocalizedStringKey {
    var stringKey: String? {
        Mirror(reflecting: self).children.first(where: { $0.label == "key" })?.value as? String
    }

    func toString(locale: Locale = .current) -> String {
        return .localizedString(for: self.stringKey ?? "", locale: locale)
    }
}

extension String {
    static func localizedString(for key: String,
                                locale: Locale = .current) -> String {
        
        let language = locale.languageCode
        let path = Bundle.main.path(forResource: language, ofType: "lproj")!
        let bundle = Bundle(path: path)!
        let localizedString = NSLocalizedString(key, bundle: bundle, comment: "")
        
        return localizedString
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.