Fixing Apple Framework APIs in regard to the Swift Design Guidelines


(David Hart) #1

I’ve only started using the transformed APIs from Apple frameworks that were auto-modified and I’ve found a few cases where the automatic translation doesn’t seem to follow the Swift Design Guidelines. I don’t know how much can be fixed manually, but if it can, it would be forth congregating as a community to prepare a massive list of proportions before the new APIs are set in stone in the fall.

Care to give feedback of what I currently have (I only did CoreMotion):

https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4

Thanks!
David.


(David Hart) #2

Inline for ease of read:

CoreMotion

<https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4#cmmotionactivitymanager>CMMotionActivityManager

Two modifications here:

Remove the starting suffix as it only really pertains to the first argument.
Rename the queue label to on to reduce the ambiguity from using two label with the same name (to).
- public func queryActivityStarting(from start: Date, to end: Date, to queue: OperationQueue, withHandler handler: CoreMotion.CMMotionActivityQueryHandler)
+ public func queryActivity(from start: Date, to end: Date, on queue: OperationQueue, withHandler handler: CoreMotion.CMMotionActivityQueryHandler)
Change to mirror the label change on CMMotionActivityManager.queryActivityStarting(from:to:to:withHandler:):

- public func startActivityUpdates(to queue: OperationQueue, withHandler handler: CoreMotion.CMMotionActivityHandler)
+ public func startActivityUpdates(on queue: OperationQueue, withHandler handler: CoreMotion.CMMotionActivityHandler)
<https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4#cmmotionmanager>CMMotionManager

Changes to mirror the label change on CMMotionActivityManager.queryActivityStarting(from:to:to:withHandler:):

- public func startAccelerometerUpdates(to queue: OperationQueue, withHandler handler: CoreMotion.CMAccelerometerHandler)
+ public func startAccelerometerUpdates(on queue: OperationQueue, withHandler handler: CoreMotion.CMAccelerometerHandler)
...
- public func startGyroUpdates(to queue: OperationQueue, withHandler handler: CoreMotion.CMGyroHandler)
+ public func startGyroUpdates(on queue: OperationQueue, withHandler handler: CoreMotion.CMGyroHandler)
...
- public func startMagnetometerUpdates(to queue: OperationQueue, withHandler handler: CoreMotion.CMMagnetometerHandler)
+ public func startMagnetometerUpdates(on queue: OperationQueue, withHandler handler: CoreMotion.CMMagnetometerHandler)
...
- public func startDeviceMotionUpdates(to queue: OperationQueue, withHandler handler: CoreMotion.CMDeviceMotionHandler)
+ public func startDeviceMotionUpdates(on queue: OperationQueue, withHandler handler: CoreMotion.CMDeviceMotionHandler)
<https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4#cmaltimeter>CMAltimeter

Change to mirror the label change on CMMotionActivityManager.queryActivityStarting(from:to:to:withHandler:):

- public func startRelativeAltitudeUpdates(to queue: OperationQueue, withHandler handler: CoreMotion.CMAltitudeHandler) {
+ public func startRelativeAltitudeUpdates(on queue: OperationQueue, withHandler handler: CoreMotion.CMAltitudeHandler) {
<https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4#cmstepcounter>CMStepCounter

Change to mirror the label change on CMMotionActivityManager.queryActivityStarting(from:to:to:withHandler:):

- public func queryStepCountStarting(from start: Date, to end: Date, to queue: OperationQueue, withHandler handler: CoreMotion.CMStepQueryHandler)
+ public func queryStepCountStarting(from start: Date, to end: Date, on queue: OperationQueue, withHandler handler: CoreMotion.CMStepQueryHandler)
The following method has two changes:

Change to mirror the label change on CMMotionActivityManager.queryActivityStarting(from:to:to:withHandler:)
The updateOn is fairly unclear as use site.
- public func startStepCountingUpdates(to queue: OperationQueue, updateOn stepCounts: Int, withHandler handler: CoreMotion.CMStepUpdateHandler)
+ public func startStepCountingUpdates(on queue: OperationQueue, updateOnStepCounts stepCounts: Int, withHandler handler: CoreMotion.CMStepUpdateHandler)
<https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4#cmmagneticfieldcalibrationaccuracy>CMMagneticFieldCalibrationAccuracy

The type is better represented as an enum.

- public struct CMMagneticFieldCalibrationAccuracy : RawRepresentable, Equatable {
- public init(_ rawValue: Int32)
- public init(rawValue: Int32)
- public var rawValue: Int32
- }
- public var CMMagneticFieldCalibrationAccuracyUncalibrated: CMMagneticFieldCalibrationAccuracy { get }
- public var CMMagneticFieldCalibrationAccuracyLow: CMMagneticFieldCalibrationAccuracy { get }
- public var CMMagneticFieldCalibrationAccuracyMedium: CMMagneticFieldCalibrationAccuracy { get }
- public var CMMagneticFieldCalibrationAccuracyHigh: CMMagneticFieldCalibrationAccuracy { get }
+ public enum CMMagneticFieldCalibrationAccuracy: Int32 {
+ case uncalibrated = -1,
+ case low
+ case medium
+ case high
+ }
<https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4#cmerror>CMError

The type is better represented as an enum conforming to ErrorProtocol:

- public struct CMError : RawRepresentable, Equatable {
- public init(_ rawValue: UInt32)
- public init(rawValue: UInt32)
- public var rawValue: UInt32
- }
- public var CMErrorNULL: CMError { get }
- public var CMErrorDeviceRequiresMovement: CMError { get }
- public var CMErrorTrueNorthNotAvailable: CMError { get }
- public var CMErrorUnknown: CMError { get }
- public var CMErrorMotionActivityNotAvailable: CMError { get }
- public var CMErrorMotionActivityNotAuthorized: CMError { get }
- public var CMErrorMotionActivityNotEntitled: CMError { get }
- public var CMErrorInvalidParameter: CMError { get }
- public var CMErrorInvalidAction: CMError { get }
- public var CMErrorNotAvailable: CMError { get }
- public var CMErrorNotEntitled: CMError { get }
- public var CMErrorNotAuthorized: CMError { get }
+ public enum CMError : UInt32, ErrorProtocol {
+ case null
+ case requiresMovement
+ case trueNorthNotAvailable
+ case unknown
+ case activityNotAvailable
+ case activityNotAuthorized
+ case activityNotEntitled
+ case invalidParameter
+ case invalidAction
+ case notAvailable
+ case notEntitled
+ case notAuthorized
+ }
<https://gist.github.com/hartbit/07b5684814e2adc2d0185138465a60b4#cmmotionactivity>CMMotionActivity

Boolean methods and properties that should read as assertions:

- public var unknown: Bool { get }
+ public var isUnknown: Bool { get }
...
- public var stationary: Bool { get }
+ public var isStationary: Bool { get }
...
- public var walking: Bool { get }
+ public var isWalking: Bool { get }
...
- public var running: Bool { get }
+ public var isRunning: Bool { get }
...
- public var automotive: Bool { get }
+ public var isAutomotive: Bool { get }
...
- public var cycling: Bool { get }
+ public var isCycling: Bool { get }


(Chris Lattner) #3

Hi David,

swift-evolution isn’t the right process for proposing changes to Apple frameworks, but you raise good points, and I really value the feedback.

If you file a radar with bugreporter.apple.com <http://bugreporter.apple.com/> and let us know the radar #, we will be happy to escalate this with the team in question. Thank you!

-Chris

···

On Jun 16, 2016, at 3:57 PM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

I’ve only started using the transformed APIs from Apple frameworks that were auto-modified and I’ve found a few cases where the automatic translation doesn’t seem to follow the Swift Design Guidelines. I don’t know how much can be fixed manually, but if it can, it would be forth congregating as a community to prepare a massive list of proportions before the new APIs are set in stone in the fall.


(Brent Royal-Gordon) #4

swift-evolution isn’t the right process for proposing changes to Apple frameworks, but you raise good points, and I really value the feedback.

If you file a radar with bugreporter.apple.com and let us know the radar #, we will be happy to escalate this with the team in question. Thank you!

Oh, I've got a list of radars to file that's as long as my arm.

To clarify: Radar is the best place to file imperfect APIs in random frameworks. Where is the best place to bring up:

1. Migrator issues?

2. Foundation issues (with the new value types)?

3. Foundation issues caused by evolution-proposed features behaving in ways that are problematic for certain uses Foundation puts them to? (Specifically, symbols marked with NSNotificationName get imported as constants on Notification.Name by default due to the design of SE-0033; you'd probably prefer they be prefix-matched and inserted into the type they belong to.)

···

--
Brent Royal-Gordon
Architechies


(Chris Lattner) #5

swift-evolution isn’t the right process for proposing changes to Apple frameworks, but you raise good points, and I really value the feedback.

If you file a radar with bugreporter.apple.com and let us know the radar #, we will be happy to escalate this with the team in question. Thank you!

Oh, I've got a list of radars to file that's as long as my arm.

To clarify: Radar is the best place to file imperfect APIs in random frameworks. Where is the best place to bring up:

1. Migrator issues?

swift-users or swift-dev (if you’re trying to improve the migrator and have questions about it).

2. Foundation issues (with the new value types)?
3. Foundation issues caused by evolution-proposed features behaving in ways that are problematic for certain uses Foundation puts them to? (Specifically, symbols marked with NSNotificationName get imported as constants on Notification.Name by default due to the design of SE-0033; you'd probably prefer they be prefix-matched and inserted into the type they belong to.)

I’d ask the folks on swift-corelibs-dev what they prefer.

-Chris

···

On Jun 18, 2016, at 10:14 PM, Brent Royal-Gordon <brent@architechies.com> wrote: