Sign In Sign Up

Sparkle appcast item metadata retrieval

For our update available state with the appcast, look at https://sparkle-project.org/documentation/api-reference/Classes/SUAppcastItem.html and show other relevant metadata if its set. For example, content length for size.

The user wants to enhance the update available state with the appcast by showing other relevant metadata from the SUAppcastItem if it's set, like content length for size.

First, I should:

  1. Read the Sparkle documentation page they referenced
  2. Find where the update available state is currently implemented in the codebase
  3. See what metadata is currently being shown
  4. Add additional relevant metadata fields like contentLength for size

Let me start by reading the Sparkle documentation and then finding the relevant code.

SUAppcastItem 5 matches
update available 2 matches

I can see the UpdateAvailableView currently only shows the version. Let me add additional metadata like content length (size), release date, and minimum OS version if available:

@@ -138,8 +138,38 @@
                                .frame(width: 50, alignment: .trailing)
                            Text(update.appcastItem.displayVersionString)
                        }
                        .font(.system(size: 11))
                        
                        if update.appcastItem.contentLength > 0 {
                            HStack(spacing: 6) {
                                Text("Size:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 50, alignment: .trailing)
                                Text(ByteCountFormatter.string(fromByteCount: Int64(update.appcastItem.contentLength), countStyle: .file))
                            }
                            .font(.system(size: 11))
                        }
                        
                        if let date = update.appcastItem.date {
                            HStack(spacing: 6) {
                                Text("Released:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 50, alignment: .trailing)
                                Text(date.formatted(date: .abbreviated, time: .omitted))
                            }
                            .font(.system(size: 11))
                        }
                        
                        if let minOS = update.appcastItem.minimumSystemVersion {
                            HStack(spacing: 6) {
                                Text("Requires:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 50, alignment: .trailing)
                                Text("macOS \(minOS)")
                            }
                            .font(.system(size: 11))
                        }
                    }
                }
                
                HStack(spacing: 8) {

Added metadata fields to the update available view:

  • Size: Shows download size using contentLength (formatted with ByteCountFormatter)
  • Released: Shows release date from date property
  • Requires: Shows minimum OS version from minimumSystemVersion

All fields only display if set in the appcast.

The labels on the left aren't wide enough and they wrap. Also remove minimum system version

The user is saying that the labels on the left aren't wide enough and they wrap. They also want me to remove the minimum system version field. Let me fix the width of the labels and remove the minOS section.

@@ -134,18 +134,18 @@
                    VStack(alignment: .leading, spacing: 4) {
                        HStack(spacing: 6) {
                            Text("Version:")
                                .foregroundColor(.secondary)
                                .frame(width: 50, alignment: .trailing)
                                .frame(width: 60, alignment: .trailing)
                            Text(update.appcastItem.displayVersionString)
                        }
                        .font(.system(size: 11))
                        
                        if update.appcastItem.contentLength > 0 {
                            HStack(spacing: 6) {
                                Text("Size:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 50, alignment: .trailing)
                                    .frame(width: 60, alignment: .trailing)
                                Text(ByteCountFormatter.string(fromByteCount: Int64(update.appcastItem.contentLength), countStyle: .file))
                            }
                            .font(.system(size: 11))
                        }
@@ -153,23 +153,13 @@
                        if let date = update.appcastItem.date {
                            HStack(spacing: 6) {
                                Text("Released:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 50, alignment: .trailing)
                                    .frame(width: 60, alignment: .trailing)
                                Text(date.formatted(date: .abbreviated, time: .omitted))
                            }
                            .font(.system(size: 11))
                        }
                        
                        if let minOS = update.appcastItem.minimumSystemVersion {
                            HStack(spacing: 6) {
                                Text("Requires:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 50, alignment: .trailing)
                                Text("macOS \(minOS)")
                            }
                            .font(.system(size: 11))
                        }
                    }
                }
                
                HStack(spacing: 8) {

Widened labels to 60pt and removed minimum system version.

Move the labels width to a constant

The user wants me to move the label width (60) to a constant instead of hardcoding it multiple times. This is good practice to avoid repetition and make it easier to change in the future.

I should add a constant at the top of the UpdateAvailableView struct (or as a fileprivate constant).

@@ -123,8 +123,10 @@
fileprivate struct UpdateAvailableView: View {
    let update: UpdateState.UpdateAvailable
    let dismiss: DismissAction
    
    private let labelWidth: CGFloat = 60
    
    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            VStack(alignment: .leading, spacing: 12) {
                VStack(alignment: .leading, spacing: 8) {
@@ -136,18 +136,18 @@
                    VStack(alignment: .leading, spacing: 4) {
                        HStack(spacing: 6) {
                            Text("Version:")
                                .foregroundColor(.secondary)
                                .frame(width: 60, alignment: .trailing)
                                .frame(width: labelWidth, alignment: .trailing)
                            Text(update.appcastItem.displayVersionString)
                        }
                        .font(.system(size: 11))
                        
                        if update.appcastItem.contentLength > 0 {
                            HStack(spacing: 6) {
                                Text("Size:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 60, alignment: .trailing)
                                    .frame(width: labelWidth, alignment: .trailing)
                                Text(ByteCountFormatter.string(fromByteCount: Int64(update.appcastItem.contentLength), countStyle: .file))
                            }
                            .font(.system(size: 11))
                        }
@@ -155,9 +155,9 @@
                        if let date = update.appcastItem.date {
                            HStack(spacing: 6) {
                                Text("Released:")
                                    .foregroundColor(.secondary)
                                    .frame(width: 60, alignment: .trailing)
                                    .frame(width: labelWidth, alignment: .trailing)
                                Text(date.formatted(date: .abbreviated, time: .omitted))
                            }
                            .font(.system(size: 11))
                        }