DA 5Star for macOS Is Now Powered by Catalyst

Published under Mango 5Star, Dec 11, 2020

Here is what’s new in the latest DA 5Star macOS version updates:

  • The macOS version is now powered by Catalyst.
  • Added Big Sur widgets support.
  • Added iCloud sync to the macOS version.

Happy cheering yourself up with the 5-star reviews ^_^

What's New in dA 5Star v2020.4

Published under Mango 5Star, Oct 30, 2020

dA 5Star v2020.4 features

dA 5Star v2020.4

DA 5Star v2020.4 is now available. What's new:

  • Added the ability to filter reviews by apps and podcasts in widget settings.
  • Added smaller fonts options in widget settings. Also slightly improved the layout in the small widget.
  • Fixed a bug where you can not add apps or podcasts not available in the US store.
  • Improved iCloud sync after reviews are re-downloaded.

Happy cheering yourself up with the 5-star reviews ^_^

What's New in dA 5Star v2020.3

Published under Mango 5Star, Oct 23, 2020

Thank you all for the great feedbacks for DA 5Star. I just released v2020.3 including the following most requested features:

  • Added the ability to filter reviews by apps and podcasts in widget settings.
  • Added smaller fonts options in widget settings. Also slightly improved the layout in the small widget.
  • Fixed a bug where you can not add apps or podcasts not available in the US store.
  • Improved iCloud sync after reviews are re-downloaded.

I am also working hard to bring the rest of your feedbacks to you in the future releases. Stay tuned.

Happy cheering yourself up with the 5-star reviews ^_^

DA 5Star for iOS and iPadOS is Launched

Published under Mango 5Star, Oct 19, 2020

DA 5Star for iOS and iPadOS is Launched

DA 5Star is 33% off until 2020-10-21.

To celebrate the launch, DA 5Star is 33% off until 2020-10-21.

App Store link: https://apps.apple.com/app/da-5star/id1473088658. If you already purchased the macOS version, you can get the iOS and iPadOS version for free.

What is DA 5Star?

DA 5Star is an iOS and iPadOS 14 home screen widget app that displays a random 5-star review of your apps and podcasts, and refreshes after however long you choose. It also has a macOS version that displays 5-star reviews as wallpapers.

Features

  • Widgets: This is the sole purpose of DA 5Star. It displays a random 5-star review of your apps and podcasts in the widget, and refreshes after however long you choose.
  • Apps and podcasts: It supports 5-star reviews of apps and podcasts on Apple platforms.
  • Custom themes: You can customize the widget themes so they fit on your home screen.
  • Review list: You can view the list of 5-star reviews of your apps and podcasts.
  • iCloud sync: Your added apps and podcasts are synced with iCloud (macOS version is not yet supported).
  • Custom app icons: It provides 5 alternative app icons.
  • Dark mode: Yes.

The story behind DA 5Star

On July 6, 2019, I was listening to EP 56: The happiest Customer of the Independence podcast. Curtis pitched this app idea:

A mac app, that will sit in your menu bar. You can feed it your iTunes connect information. And it will go to your ratings, pull random 5-star rating every however many hours. And have like kind that those motivational quote things, but have in your wallpaper.

After hearing it, I just couldn't stop thinking about it. As developers, we all experienced those 1-star ratings that ruin our day or week. We humans are bad at ignoring them. We fail to remind ourselves that there are more important 5-star customer ratings out there. So I immediately created the Xcode project and started implemented. On the next day I sent the hosts @eataduckimust, @parrots, @jellybeansoup a demo. I got great feedbacks and launched the first version in two weeks. I later then released 5 updates to improve it.

I didn't expect other huge updates to the app. Until one day after 2020's WWDC, I realized that this app is now viable after the introduction of iOS 14 home screen widgets. So the iOS version was born.

NOTE: The initial macOS version was a $1.99 (USD) paid upfront app. I decided to raise the price to $2.99 (USD) with the launch of the iOS and iPadOS version (it's a universal purchase). But I'm keeping the original price for another three days, so it's effectively a 33% off launch sale.

Again, you can purchase DA 5Star here: https://apps.apple.com/app/da-5star/id1473088658.

SwiftUI: Set a Max Width on Spacer()

Published under Mango Snippets, Oct 5, 2020

SwiftUI's Spacer() has a minLength parameter, but some times we also want a maxLength. There isn't one, but you can use .frame(maxWidth:) to achieve the same effect:

Spacer()
    .frame(maxWidth: 16)

SwiftUI: How To Programmatically Make a TextField First Responder

Published under Mango Snippets, Oct 5, 2020

It's a common scenario to make a text field first responder when it first appears. A typical example is the login screen. As soon as it appears, you want the account field to be in focus and the keyboard to appear. Then the user can start typing right way.

SwiftUI in iOS 15 introduced a new property wrapper called @FocusState. It allows you to control which input has focus. It can be bound to a Bool or an enum:

struct ContentView: View {
    @FocusState private var focused: Bool
    @State private var name = "Mango Umbrella"

    var body: some View {
        VStack {
            TextField("Name", text: self.$name)
                .focused(self.$focused)
            Button("Focus on name") {
                self.focused = true
            }
        }
    }

But how can you make the text field focus as soon as the view appears? You can't assign an initial value to the property. Another thought is to change its value in .onAppear like this:

struct ContentView: View {
    @FocusState private var focused: Bool

    var body: some View {
        VStack {
            // ...
        }
        .onAppear {
            self.focused = true
        }
    }
}

This won't work unfortunately. It appears that @FocusState only works when the view has been rendered after some time. A not-so-good workaround is to add a delay:

struct ContentView: View {
    @FocusState private var focused: Bool

    var body: some View {
        VStack {
            // ...
        }
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                self.focused = true
            }
        }
    }
}

I don't recommend this approach though. The delay is arbitrary, and slower devices might need a longer delay. It isn't a great user experience anyway.

For this task, it's best falling back to UIKit's becomeFirstResponder(). It's easy to wrap a UITextField in a UIViewRepresentable like this:

struct MyTextField: UIViewRepresentable {
    typealias UIViewType = UITextField

    @Binding var becomeFirstResponder: Bool

    func makeUIView(context: Context) -> UITextField {
        return UITextField()
    }
    
    func updateUIView(_ textField: UITextField, context: Context) {
        if self.becomeFirstResponder {
            DispatchQueue.main.async {
                textField.becomeFirstResponder()
                self.becomeFirstResponder = false
            }
        }
    }
}

Notice the async call. It is necessary because it's modifying the state and it isn't allowed in updateUIView. If you forget, Xcode will warn you Modifying state during view update, this will cause undefined behavior.

To make it first responder when the view appears, just call it in .onAppear. And it works without a delay:

struct ContentView: View {
    @State private var becomeFirstResponder = false

    var body: some View {
        MyTextField(becomeFirstResponder: self.$becomeFirstResponder)
            .onAppear {
                self.becomeFirstResponder = true
            }
    }
}

TIP: If you use SwiftUI Instrospect, you can directly inspect the backing UITextField without your own wrapper:

struct ContentView: View {
    @State private var name = "Mango Umbrella"
    @State private var becomeFirstResponder = true

    var body: some View {
        TextField("Name", text: self.$name)
            .introspectTextField { textField in
                if self.becomeFirstResponder {
                    textField.becomeFirstResponder()
                    self.becomeFirstResponder = false
                }
            }
        }
    }
}

∞ Apple Publishes New Webpages Explaining the Benefits of the App Store and the Company’s Developer Program

Published under Mango Paper, Sep 24, 2020

The more PR effort Apple puts into this, the worse their image is. Wake up.

SwiftUI: How To Draw Borders With Rounded Rectangles

Published under Mango Snippets, Jul 23, 2020

In SwiftUI, it’s easy to find out there is a .border modifier, and a .cornerRadius modifier. However, those tools can’t create borders with rounded corners. Instead, you can use the .overlay modifier with a RoundedRectangle shape:

Text("DA Tips")
    .padding()
    .overlay(
        RoundedRectangle(cornerRadius: 16)
            .stroke(Color.pink, lineWidth: 2)
    )

Swift: How To Count Occurrences of a Character in a Swift String

Published under Mango Snippets, Jul 21, 2020

To count occurrences of a character in a Swift String, you can use Sequence.filter and then Array.count:

"Mango Snippets".filter({ $0 == "n"}).count

Output:

2

DA CamCal is Now FREE

Published under Mango Exposure, May 3, 2020

To give more people the choice, DA CamCal is now FREE with ads by default. You can still pay a one time fee to remove them. Don't worry if you have previously purchased the app (thank you!), you won't see ads.

Happy photographing no matter where you are.

-- Dolee ^_^

« Previous page Page 11 of 51 Next page »