Skip to content

Initial .sink or .map doesn't fire for optional @Published properties if they start at nil #12

@joshuakcockrell

Description

@joshuakcockrell

If you have a
@published var email: String? = nil or any optional that starts at nil, .sink will emit a value on iOS but not on Skip transpiled Android.

class Manager: ObservableObject {
  static let shared = Manager()
  private var subscribers: Set<AnyCancellable> = []
  private init() {
    self.$email.sink { e in
      print("New email: \(e ?? "nil")")
    }
    .store(in: &subscribers)
    
    DispatchQueue.main.async {
      self.email = nil // Emits value on both platforms
    }
  }
  @Published var email: String? = nil // Initially emits nothing on Android
}

struct AlertPlayground: View {
  
  @ObservedObject var manager = Manager.shared

Expected output (how it works on iOS:

New email: nil
New email: nil

Actual output (initially doesn't emit a value)

New email: nil

Context from Slack: https://skiptools.slack.com/archives/C078X69G8F2/p1748547032624249?thread_ts=1748494655.362589&cid=C078X69G8F2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions