Why there is a TimeZone with an API significantly different than NSTimeZone?
Say NSTimeZone has init(name: String) and TimeZone does not.
NSTimeZone has abbreviation property and in TimeZone abbreviation is a function that takes Date as a parameter (and nil is not an option)
Interestingly enough TimeZone(identifier:)
digests abbreviations just fine.
The Foundation framework offers quite a few type pairs where the API of the original
NS-prefixed type, as imported from the original Objective-C code, was less than optimal for Swift. Among these type pairs areNSDate/Date,NSURL/URLNSData/Dataand others.
TimeZoneandNSTimeZoneare one such pair, whereNSTimeZoneis an Objective-C type which is exposed to Swift as-is, whileTimeZoneis a native Swift wrapper aroundNSTimeZonewith an updated API. That updated API is intentionally different, because the original Objective-C API may be suboptimal in Swift.For example, as you note,
NSTimeZoneoffers both anabbreviationproperty and an-abbreviationForDate:method, whileTimeZoneonly offers the method. It's important to note that theabbreviationproperty just returns the result of calling-abbreviationForDate:, passing in[NSDate now]; i.e., it exists only because Objective-C doesn't support default arguments for methods, soabbreviationis a convenience. Swift, however, does have default arguments, soTimeZone.abbreviation(for:)unifies these: if you want to pass a specificDate, you can, but you don't have to.There are other reasons for disparate APIs on paired types like this:
-[NSTimeZone initWithName:]is an API that's poorly named: although its parameter is called "name", the actual argument is supposed to be a time zone identifier, which has a completely different format. This has to be called out in theNSTimeZonedocumentation in several places (e.g., "Although many NSTimeZone symbols include the word “name”, they actually refer to IDs."), which isn't great: ideally, the API should speak for itself. WhenTimeZonewas introduced, the Foundation team had an opportunity to improve on the name of the API, so they introduced the same initializer onTimeZoneasTimeZone.init(identifier:)Following the Foundation conventions of mutable collections,
NSDatais an immutable data type which has a mutable counterpart inNSMutableData. Beside the complications that come fromNSMutableDatabeing a subclass ofNSData(andNSDatabeing a "class cluster"), Swift doesn't need to make this sort of distinction: when you work with value types, you don't need both mutable and immutable variants — you get mutability withvar/let.Data, then, is a value type implementation which unifies the interfaces thatNSDataandNSMutableDataoffer into a single type (also removing some warts along the way)Many language features in Swift are difficult to replicate on existing Objective-C types, or would require a complete rethink of the type and its interface in order to be effective in Swift. This is the case with
NSAttributedString/NSMutableAttributedStringandAttributedString:NSAttributedStringis an extremely dynamic type, offering few available tools for convenience and safety;AttributedStringmakes use of a wide range of tools that Swift provides to offer type safety, autocompletion, and a host of conveniences that necessarily require a completely different API surfaceIn all, it's very rare for the Swift variant of a type pair like this to offer less API than its Objective-C counterpart — and where API was removed, it's almost always for safety, ergonomics, or in favor of better APIs. But in general, the Swift variants typically have significantly more functionality, even if how that functionality is accessed is a little different.