Archive for March 17, 2023

Friday, March 17, 2023

Amazon Shuts Down Newspaper and Magazine Subscriptions

Laura Hazard Owen (via Hacker News):

It doesn’t matter whether they’re for your Kindle or in print — starting this week, Amazon is no longer selling newspaper and magazine subscriptions.

[…]

Instead, Amazon wants publishers to add their content to its $9.99/month digital subscription program, Kindle Unlimited, which includes a bunch of magazines and access to one newspaper that I saw — USA TODAY.

[…]

Anyway, while this all feels very 2011, news publishers in particular should check out some of the comments on last week’s Reddit thread, where customers talk about why they liked reading newspapers on Kindle, and why they’re sorry to lose the subscriptions — and it still has to do with the “satisfying reading experience” Sulzberger talked about more than a decade ago.

Previously:

Who Can Access Private Home Security Footage

Alfred Ng (via Hacker News):

The police said they were conducting a drug-related investigation on a neighbor, and they wanted videos of “suspicious activity” between 5 and 7 p.m. one night in October. Larkin cooperated, and sent clips of a car that drove by his Ring camera more than 12 times in that time frame.

He thought that was all the police would need. Instead, it was just the beginning.

They asked for more footage, now from the entire day’s worth of records. And a week later, Larkin received a notice from Ring itself: The company had received a warrant, signed by a local judge. The notice informed him it was obligated to send footage from more than 20 cameras — whether or not Larkin was willing to share it himself.

Previously:

The Magic Highlighter 0.6

Caleb Hailey:

If you’re like us, you might have developed a habit of smashing the ⌘-F keyboard shortcut and repeating some or all of the exact same search terms you already submitted to the search engine (e.g. Google, DuckDuckGo, or Bing).

[…]

The Magic Highlighter is a brand new Safari Extension that automatically highlights your Google.com, DuckDuckGo.com, and Bing.com search terms and phrases on search result web pages — saving you time, and helping you find what you’ve been searching for.

This is referring to the actual found pages, not the lists of search results. It’s a $1.99 universal purchase.

Equality in Swift: NSObject, Subclasses, and Existentials

Mark Newton:

Conformance to the Equatable protocol seems pretty straightforward. You simply override the == function.

[…]

This works great for objects like structs, or classes with no superclass. However, we can run into problems with the == function if we’re dealing with NSObject subclasses.

Jayesh Kawli (via Marcin Krzyzanowski):

And now if you try to do following comparison, they will either won’t work, will be buggy or fail to compile

Noah Gilmore:

Swift can be tricky sometimes. For example, what does the following print?

class A: NSObject {
  let x: Int

  init(x: Int) {
    self.x = x
  }
}

func ==(left: A, right: A) -> Bool {
  return left.x == right.x
}

print(A(x: 1) == A(x: 1))
print([A(x: 1)] == [A(x: 1)])

[…]

The best way to make an NSObject subclass use custom equality inside an array is to override isEqual:[…]

His reasoning for why the custom == didn’t work as expected is wrong, but the solution is correct. Similarly, you should override hashValue (not hash(into:)) if you need to change how it is Hashable.

For non-NSObject classes, a similar issue applies. If you have something like:

class Base: Equatable {
    static func == (lhs: Base, rhs: Base) -> Bool {
        return lhs === rhs
    }
}

class A: Base {
    let x: Int

    init(x: Int) {
      self.x = x
    }
}

func ==(left: A, right: A) -> Bool {
    return left.x == right.x
}

The results may not be what you expect:

A(x: 1) == A(x: 1) // true
[A(x: 1)] == [A(x: 1)] // false

Array uses the == from where its elements conformed to Equatable.

Natalia Panferova (tweet):

In Swift 5.7 that comes with Xcode 14 we can more easily check if two values of type Any are equal, because we can cast values to any Equatable and also use any Equatable as a parameter type thanks to Unlock existentials for all protocols change.

[…]

Inside isEqual() method we have access to Self, so we can try to cast the other value to the same type as the concrete type of the value this method is called on. If the cast fails, the two values cannot be equal, so we return false. If it succeeds, then we can check the two values for equality, using == function on values of the same concrete type.

There are some edge cases to be aware of, however, so it is preferred to use AnyHashable.

Ben Cohen:

You can define something similar for Comparable[…]

Previously:

Update (2023-08-09): See also: Helge Heß.