Moq: how to VerifySet with an object that respects a condition

Sometimes you want to test that a service method sets up the correct object on another (singleton) service. For example, that an authentication service sets up a user object with the correct username to the app’s user context.

With Moq you could assume this is simple (and you would be right), but if you usually only need to verify method calls occuring on your mocks, you may have a difficult time to find the right syntax for checking the setter execution, especially as the set object also needs to respect a condition. So here is some code for the example described above (note that SetupSet is not needed here, unless we’d want to make it “globally” verifiable):

...
public class AuthenticationService
{
  ...
  public void Logon(String username)
  {
    userContext.User = new User { Username = username };
  }
}
// Arrange
var userContextMock = Mock<IUserContext>();
var authenticationService = new AuthenticationService(userContext);
// Act
authenticationService.Logon(username: "John");
// Assert
userContextMock.VerifySet(m => 
  m.User = It.Is<User>(u => u.Username == "John"));
Advertisements
Posted in C# | Tagged , , , | Leave a comment

Daylight may ruin your date

blur close up date dates

Fotografie de Pixabay pe Pexels.com

(No, this post doesn’t include dating advice. For such content, your best shot is probably YouTube. :-))

This is instead about Date values in Swift*. Which sometimes you might need to update by “components”. Such as by adding a specific number of days to them. And about the fact that you might – or might not – realize that, depending on which way you attempt to do it, on the actual source date value and the number of days to add to it, and finally on the target system’s settings as well (specifically when the timezone is daylight saving time enabled), the result would have a different time of day and may ruin your application!

* The concepts to be discussed apply to many other development technologies too.

Moreover, date updating code could easily pass many reasonable unit tests and all system tests if they are all done with a dataset that just doesn’t fall into a specific time range. And the issue could then happen only in production, causing strange bugs your users will surely “love”. (And you might need to solve those bugs on Easter day.)

E.g. if your initial Date value was 1/1/2001 00:00 UTC, after adding 175 days (i.e. 25 weeks) to it, the result could be found to be 6/24/2001 23:00 UTC! But if you try it only with 1 and 2 days added (and even with -1), it would work just fine, always returning dates with 00:00 UTC as result.

Try it on your Mac if you don’t believe me (but as I already mentioned, you need to have your system/profile configured to use a timezone with daylight saving time enabled):

import Foundation

// Prepare a date formatter to always show dates using UTC
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
dateFormatter.timeZone = TimeZone.init(secondsFromGMT: 0)

// Prepare a reference date (1/1/2001)
let referenceDate = Date(timeIntervalSinceReferenceDate: 0)
print("ref:", dateFormatter.string(from: referenceDate))

// Do a first test
let date1 = Calendar.current.date(byAdding: .day, value: 1, to: referenceDate)!
print("date1", dateFormatter.string(from: date1))

// Do another test
let date2 = Calendar.current.date(byAdding: .day, value: 175, to: referenceDate)!
print("date2:", dateFormatter.string(from: date2))

If you run the above on a system with daylight saving time offset of 1 hour of a northern hemisphere country, you’d see this result, regardless of the timezone’s offset from UTC:

ref: 01/01/2001, 00:00
date1: 02/01/2001, 00:00
date2: 24/06/2001, 23:00

You guessed it: the problem is that although we have configured the DateFormatter to always use UTC timezone without daylight saving (GMT+0), the current Calendar object also has a TimeZone, and that is the current timezone. And the call on the current calendar to compute a date by adding that specific number of days seems to use the daylight saving time settings of the calendar’s timezone (i.e. those of the end user’s timezone) to internally compute the output value. And summer daylight saving time is enabled for June, but not for January nor December for a northern hemisphere DST-enabled timezone.

The fix is then very simple – the real problem here was just to do the right test and realize the issue (lesson learned: always think about and test with multiple date values, time zones, and daylight saving time settings when working with dates and times):

// Prepare generic UTC time zone
let genericTimeZone = TimeZone.init(secondsFromGMT: 0)!
...
dateFormatter.timeZone = genericTimeZone
...

// Prepare a generic UTC-based calendar for computing dates by differences
var genericCalendar = Calendar(identifier: .gregorian)
genericCalendar.timeZone = genericTimeZone

// Do a first test
let date1 = genericCalendar.date(byAdding: .day, value: 1, to: referenceDate)!
print("date1:", dateFormatter.string(from: date1))

// Do another test
let date2 = genericCalendar.date(byAdding: .day, value: 175, to: referenceDate)!
print("date2:", dateFormatter.string(from: date2))
ref: 01/01/2001, 00:00
date1: 02/01/2001, 00:00
date2: 25/06/2001, 00:00
Posted in Swift | Tagged , , , , , | Leave a comment

Swift optionals can save the day

Although generics in Swift are somehow limited at this time, there is a nice variance-related feature available when using optionals: you can assign a non-optional to an optional variable, an array of non-optionals to an array of optionals (these two are classics), but similarly you can use a function with a non-optional argument where a closure with optional argument is expected:

// Var
let i: Int? = 1

// Array
let ints: [Int?] = [1, 2]

// Func
func funcWithOptionalInt(i: Int?) {
    print(i)
}
let funcWithInt: (Int) -> Void = funcWithOptionalInt
funcWithInt(1)

This prints out “Optional(1)”, of course. But why do I think this is a such a great feature? Because this thingy can be used in a common situation like this:

Let’s assume that we need to perform an action repeatedly, and the first time it should be performed immediately, i.e. before returning from the current call. Like begin and repeat:

import Foundation

// Support for running this in a playground:
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

func execute(_: Timer) {
    print("Done")
}
execute() // This won't compile: execute requires a Timer argument.
let _ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, 
                                                    block: execute)

As you can see, we just cannot run the execute function one time “manually”, i.e. before scheduling the timer on it. There are a few standard solutions for this, of course, such as to define another execute method without an argument, and call it from the one with the Timer argument; or to call a fire() method immediately after the Timer is initialized.

But I didn’t like any of them too much (actually I’d really hate using the second one.)

And – because optionals work as described above – it seems there is a nicer way to solve the issue: to define the execute function as accepting an optional Timer argument with a default value of nil. That’s all, now everything would work, including that initial execute call, as the block closure required by scheduledTimer accepts any function with an argument of type Timer or an optional Timer! (And that default value helps us when there is no Timer object available yet to be passed to the function at all):

func execute(_: Timer? = nil) {
    print("Done")
}
execute()
let _ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true,
                                                    block: execute)

 

Posted in Swift | Tagged , , , | Leave a comment

Enum cases with associated values are powerful but we need follow-up patterns

colors palette

Fotografie de Kaboompics .com pe Pexels.com

Let’s assume we want to use Swift to develop a function to round floating point numbers, in different ways according to a context. For example, sometimes the result of such rounding could be the input value itself (like on a continuous number scale), and other times an integral value computed using the standard rule instead:

func rounding(_ value: Double, on scale: Scale) -> Double {
    switch scale {
    case .continuous:
        return value
    case .integers:
        return value.rounded()
    }
}
enum Scale {
    case continuous
    case integers
}
print(rounding(3.1, on: .integers)) // prints 3.0

So far, so good. But what if we’d want to also allow rounding to limits of intervals of a specific length, i.e. periods (or, later, even exponential or logarithmic intervals) starting from a specific origin? And maybe supporting multiple rounding rules as well? Swift can help us by supporting arguments (called associated values) on our enum cases, indeed:

func rounding(_ value: Double, on scale: Scale) -> Double {
    switch scale {
    ...
    case .intervals(let period, let origin, let roundingRule):
        return origin + ((value - origin) / period).rounded(roundingRule) * period
    }
}
enum Scale {
    ...
    case intervals(period: Double, origin: Double, roundingRule: FloatingPointRoundingRule)
}
print(rounding(3.1, on: .intervals(period: 2, origin: 0, roundingRule: .toNearestOrAwayFromZero))) // prints 4.0

But – oh, oh – we cannot have defaults for the origin and roundingRule arguments above: Swift enum cases simply don’t support that (and you can’t have secondary usage labels for the arguments either). So what we can do?

We can define an Info struct to hold our arguments together, and define a custom initializer for that to get what we want. Somewhat:

func rounding(_ value: Double, on scale: Scale) -> Double {
    switch scale {
    ...
    case .intervals(let info):
        let period = info.period, origin = info.origin
        return origin + ((value - origin) / period).rounded(info.roundingRule) * period
    }
}
enum Scale {
    case continuous
    case integers
    case intervals(_: ScaleInfo)
}
struct ScaleInfo {
    init(period: Double, origin: Double = 0, roundingRule: FloatingPointRoundingRule = .toNearestOrAwayFromZero) {
        self.period = period
        self.origin = origin
        self.roundingRule = roundingRule
    }
    var period: Double
    var origin: Double
    var roundingRule: FloatingPointRoundingRule
}
print(rounding(3.1, on: .intervals(ScaleInfo(period: 2)))) // prints 4.0

As you can see, the client code in the last line doesn’t need to provide origin, nor roundingRule arguments anymore, since now it just needs to construct an Info object at that time, and its initializer has default values for those (usually unneeded) arguments.

But I feel this is still too verbose, because now we need to specify the struct’s name (ScaleInfo) when using the intervals enum case. (Ugly.)

The final piece of advice here is to add a static helper method on the enum itself, returning the case with the info object pre-constructed. (Note that this also requires us to use optional arguments to avoid redefining their default values and nil to actually postpone selecting such defaults – actually another pattern that I like and use often, separately):

enum Scale {
    ...
    case intervals(_: ScaleInfo)
    static func intervalsWith(period: Double, origin: Double? = nil, roundingRule: FloatingPointRoundingRule? = nil) -> Scale {
        return .intervals(ScaleInfo(period: period, origin: origin, roundingRule: roundingRule))
    }
}
struct ScaleInfo {
    init(period: Double, origin: Double? = nil, roundingRule: FloatingPointRoundingRule? = nil) {
        self.period = period
        self.origin = origin ?? 0
        self.roundingRule = roundingRule ?? .toNearestOrAwayFromZero
    }
    ...
}
print(rounding(3.1, on: .intervalsWith(period: 2))) // prints 4.0

And we’re done. Now the client code simply calls .intervalsWith(period: 2) and gets everything running as before, without knowing anything about the Info struct anymore. (And it’s so readable!)

The single issue I find remaining is the need of selecting a different name for the static method helper itself – intervalsWith – as it’s not possible to name it similarly to an existing case entry (the way I’d otherwise have wished to go with.)

Note that while naming conventions in Swift won’t usually allow us to add a preposition as suffix to a method name and would recommend to use an argument usage label instead, e.g. intervals(with period: Double), there is an exception to this rule: it’s OK like that when multiple arguments are accepted together as an object for the preposition (and we do accept multiple arguments in our case, even if some have default values and may eventually be omitted), so – luckily – we don’t break anything!

And finally, we must just observe how great is that Swift supports static methods defined within enum types (actually, it does support instance methods as well). This way we can get the environment even proposing the helper call when the client developer types the period character that usually precedes literal enum values! (And that’s just perfect!)

But wait, do you see now what I see? We don’t need the Info struct anymore! (And optional arguments can optionally go away with it too.) Here is the code simplified back:

func rounding(_ value: Double, on scale: Scale) -> Double {
    switch scale {
    ...
    case .intervals(let period, let origin, let roundingRule):
        return origin + ((value - origin) / period).rounded(roundingRule) * period
    }
}
// removed struct ScaleInfo { ... }
enum Scale {
    ...
    case intervals(period: Double, origin: Double, roundingRule: FloatingPointRoundingRule)
    static func intervalsWith(period: Double, origin: Double = 0, roundingRule: FloatingPointRoundingRule = .toNearestOrAwayFromZero) -> Scale {
        return .intervals(period: period, origin: origin, roundingRule: roundingRule)
    }
}
print(rounding(3.1, on: .intervalsWith(period: 2))) // prints 4.0

Update: It seems people are working to solve this in a better (first class syntax) way!

Posted in Swift | Tagged , , , , , , | Leave a comment

Swift events: almost generic, almost solution(s)

man wearing black and white stripe shirt looking at white printer papers on the wall

Fotografie de Startup Stock Photos pe Pexels.com

I have been thinking about a possible better/generic solution for adding multi-cast delegate/event dispatching support to Swift class hierarchies since January, i.e. since more than 6 months ago.

While in my opinion the solution below is still not better than the one I proposed back then, being less type safe unfortunately, I wanted to post it anyway, maybe it could help somebody who cares more than me about avoiding boilerplate code (or until first class event entities would eventually reach us in a following Swift update, who knows.)

Disclaimer: I know (and I already mentioned in that earlier post) that there is already a pretty good generic solution proposed by Greg Read, but I struggled to find something without AnyObject internal checks. Note that applying a type condition like T: AnyObject in his code does work but introduces new issues – try it yourself – as Swift would then not allow the delegates variable definition within the client class anymore even if you’d add a Delegate: class clause too – it really needs a class type, not a protocol type then! (Moreover, of course, his WeakWrapper class can also be changed to a struct and some parts of the code need to be adapted a bit to work with Swift 4, but these are side stories.)

So let’s move back a bit, and try something else:

class EventDispatcher {
    func addHandler(_ newHandler: EventHandler) {
        handlers.append(EventHandlerReference(object: newHandler))
    }
    func removeHandler(_ oldHandler: EventHandler) {
        guard let index = handlers.index(where: { handler in handler.object === oldHandler }) else { return }
        handlers.remove(at: index)
    }
    func raise(_ argument: Any) {
        for handler in handlers {
            handler.object?.handle(argument)
        }
    }
    private var handlers = [EventHandlerReference]()
    private struct EventHandlerReference {
        weak var object: EventHandler?
    }
    deinit {
        print("Dispatcher deinit")
    }
}
protocol EventHandler: class {
    func handle(_ argument: Any)
}

As you can see the idea is to extract adding, removing, and raising events (i.e. managing and calling handler delegates) into a Dispatcher class, to be instanced by each service, therefore without having to duplicate the internal code in the service classes themselves. Similar, somewhat, to Greg’s solution, but in our case the EventHandler protocol is not service-specific anymore.

Of course, the private wrapper class (EventHandlerReference) is needed to actually store weak delegate references so that all objects (clients and services) get properly deinitialized eventually – considering Swift‘s ARC context – similarly to the way we do it in the non-generic version (and to the way Greg does it as well).

Update: With Xcode 10+, you can now directly remove array items that respect a predicate, so the handler removal is now easier:

func removeHandler(_ oldHandler: EventHandler) { 
  handlers.removeAll(where: { handler in handler.object === oldHandler })
}

The main problem with this approach, however, is that EventHandler protocol must not be generic, i.e. it simply can’t have an Argument associated type or otherwise we couldn’t have a list of handlers stored at the dispatcher level (Swift is not C#!)

The only possible solution I could think of in order to get something running, though, was to define a common protocol for the arguments passed when raising and handling events, or, why not?, just use the most simple existing one: Any!

Services can then raise events through a dispatcher object that they would initialize themselves, and clients could handle them by simply implementing the EventHandler protocol:

class Service {
    init(_ name: String) {
        self.name = name
    }
    var name: String
    var dispatcher = EventDispatcher()
    func doSomething(_ info: String) {
        dispatcher.raise(EventType.somethingWasDone(info: info, source: self))
    }
    enum EventType {
        case somethingWasDone(info: String, source: Service)
    }
    deinit {
        print(name, "deinit")
    }
}
class Client: EventHandler {
    init(_ name: String, subscribingTo service: Service) {
        self.name = name
        self.service = service
        service.dispatcher.addHandler(self)
    }
    var name: String
    var service: Service
    func handle(_ argument: Any) {
        guard let type = argument as? Service.EventType else { return }
        switch (type) {
        case .somethingWasDone(let info, let source):
            print(self.name, "observes that something was done about", info, "on", source.name)
        }
    }
    deinit {
        print(name, "deinit")
    }
}

As you can see, the service class can define a custom enum (or any other type) for specifying the event types that it wants to be able to raise, and clients could handle them using switch statements (or otherwise checking the argument values they receive) in their handler method. However, since Swift enum values can also have supplemental arguments themselves, event related information and/or the source of event (the service instance that raises it) can be easily passed to the handler together with the event type.

But in my opinion, an ugly thing must, unfortunately, be done by the client developer anyway: narrow down the event argument value to the known type (e.g. Service1.EventType). As if this was a (too generic) message bus implementation!

let type = argument as? Service.EventType

This line is the one I don’t like at all, and it’s mostly why I think I’d keep using the January (non-generic) solution, myself; besides being more expressive, it’s way more type safe.

But if you want to use the generic idea in your application or framework, don’t forget to remove all deinitializers from the code first – I’ve added them just to be able to check that we don’t get any unexpected reference cycles formed.

For reference purposes – maybe to determine whether or not you can use it – here is some sample usage code and screen output below:

func run() {
    let service1 = Service("S1")
    let service2 = Service("S2")
    let client1 = Client("C1", subscribingTo: service1)
    let client2 = Client("C2", subscribingTo: service2)
    service1.doSomething("a") // C1 handles somethingWasDone("a") for S1
    service1.dispatcher.addHandler(client2)
    service2.dispatcher.addHandler(client1)
    service2.doSomething("b") // C1 and C2 handle somethingWasDone("b") for S2
    service2.dispatcher.removeHandler(client1)
    service2.doSomething("c") // C2 handles somethingWasDone("c") for S2
}
run()
C1 observes that something was done about a on S1
C2 observes that something was done about b on S2
C1 observes that something was done about b on S2
C2 observes that something was done about c on S2
C2 deinit
C1 deinit
S2 deinit
Dispatcher deinit
S1 deinit
Dispatcher deinit

Finally, I must say that there is yet another – more generic/type safe, but not surely better – solution (which I’ve reached to after reading some good StackOverflow debates on miscellaneous Swift amazing features and… amazing lack of features), requiring client developers to define closure typed variables (lazy if they need access to self from within the code) as event handlers. Personally I don’t like this solution too much either because it needs capturing either unowned self or field values of the current client object in order to avoid ARC traps, but again, maybe it is useful for somebody who does both service and client development within an app, rather than publishing a framework:

class Event<Argument> {
    func addHandler(_ newHandler: EventHandler<Argument>) {
        handlers.append(EventHandlerReference(object: newHandler))
    }
    func removeHandler(_ oldHandler: EventHandler<Argument>) {
        guard let index = handlers.index(where: { handler in handler.object === oldHandler }) else { return }
        handlers.remove(at: index)
    }
    func raise(_ argument: Argument) {
        for handler in handlers {
            handler.object?.function(argument)
        }
    }
    private var handlers = [EventHandlerReference]()
    private struct EventHandlerReference {
        weak var object: EventHandler<Argument>?
    }
    deinit {
        print("Event deinit")
    }
}
class EventHandler<Argument> {
    init(_ function: @escaping (Argument)->Void) {
        self.function = function
    }
    var function: (Argument)->Void
    deinit {
        print("Event handler deinit")
    }
}
class Service {
    init(_ name: String = "default") {
        self.name = name
    }
    var name: String
    func doSomething(_ info: Int) {
        somethingWasDone.raise(info)
    }
    var somethingWasDone = Event<Int>()
    deinit {
        print("Service deinit")
    }
}
class Client {
    init(_ name: String, subscribingTo service: Service) {
        self.name = name
        self.service = service
        service.somethingWasDone.addHandler(somethingWasDoneHandler)
    }
    var name: String
    var service: Service
    lazy var somethingWasDoneHandler = EventHandler<Int> { [name] argument in
         print(name, "observes that something was done about", argument)
    }
    deinit {
        print("Client deinit")
    }
}
func run() {
    let service1 = Service("S1")
    let service2 = Service("S2")
    let client1 = Client("C1", subscribingTo: service1)
    let client2 = Client("C2", subscribingTo: service2)
    service1.doSomething(1)
    service2.somethingWasDone.addHandler(client1.somethingWasDoneHandler)
    service2.doSomething(2)
    service2.somethingWasDone.removeHandler(client1.somethingWasDoneHandler)
    service2.doSomething(3)
}
run()
C1 observes that something was done about 1
C2 observes that something was done about 2
C1 observes that something was done about 2
C2 observes that something was done about 3
Client deinit
Event handler deinit
Client deinit
Event handler deinit
Service deinit
Event deinit
Service deinit
Event deinit
Posted in Swift | Tagged , , , , | Leave a comment

ToolTipService.ShowDuration within a specific WPF view

ToolTipService.ShowDuration attached property isn’t inherited from parent to child elements within the WPF visual tree, and therefore values for this property – to produce runtime effects – must be set on all the elements that have ToolTips for which we’d want to change the display duration (i.e. their placement targets.)

Often this is not easy to do, especially if we use components that have internal elements with tool tips that we don’t have direct access to (other than – maybe periodically? – browsing the visual tree programmatically, of course.)

To solve the issue, however, sometimes we can simply define a different default value for ToolTipService.ShowDuration property in the entire application:

ToolTipService.ShowDurationProperty.OverrideMetadata(
    typeof(DependencyObject), new FrameworkPropertyMetadata(30000)); // 30s

But sometimes we’d want to apply a different show duration value only within a specific view within the app, not everywhere. We’d then need to find a better way to do it, i.e. only for the placement target elements of the tool tips that are opening within that part of the visual tree governed by the root view element.

WPF offers a ToolTip.Opened routed event that should help, but because tool tips are not in the main visual tree, the routed events from their side won’t bubble up that much as we would need, so unfortunately this won’t actually work:

<my:Component ToolTip.Opened="MyComponent_ToolTipOpened">
  ...
</my:Component>

What we can do, though, is to try to register the event handler with a style and an event setter. I’ve tested and this solves the problem for good, indeed! Enjoy:

<my:Component>
  <my:Component.Resources>
    <Style TargetType="ToolTip">
      <EventSetter Event="Opened" Handler="MyComponent_ToolTipOpened"/>
    </Style>
  </my:Component.Resources> 
</my:Component>
private void MyComponent_ToolTipOpened(object sender, RoutedEventArgs e)
{
  var toolTip = e.Source as ToolTip;
  var element = toolTip.PlacementTarget;
  ToolTipService.SetShowDuration(element, 30000); // 30s
}
Posted in WPF | Tagged , , ,

Drag gesture recognizer for iOS/macOS development (with initial location)

blur casual cellphone close up

Photo by Porapak Apichodilok on Pexels.com

As everybody knows, when using a mouse on a computer a drag operation occurs when the mouse button is pressed, then the device is moved, and eventually the button is released. It’s a continuous and precise operation.

In iOS we have (less precise) touches instead, but sometimes we do want to react to a drag operation similarly, upon beginning, moving, and eventually ending touches.

UIPanGestureRecognizer does a pretty good job to identify such drag operations itself, except that when it reaches its began state, the user has already moved the touch(es) a bit and we don’t know the initial location anymore – there’s no locationInViewWhenTouchesBegan property – while we’d need it to accurately compute coordinate deltas for responding to the drag operation.

(In a way that is expected, because we don’t want the pan operation to begin immediately when the first touch begins – as we are waiting to see if the user wants to actually pan or do something else.)

Update: While this is annoying, it is the way NSPanGestureRecognizer works with mouse events in macOS Cocoa development too, just that it is very difficult to see the behavior there; to catch the issue, you’d need to start dragging with the mouse from a limit of the draggable area of an element, towards the space outside that element.

To solve this problem (at least today) we need to specialize the recognizer class ourselves, reading and preserving the location in view when the touches actually begin, and use the specialization instead. Note below how we define an initial-location-in-view property for this purpose. (You would need to make the class and property public if you would want to use them outside a framework, though.)

import UIKit.UIGestureRecognizerSubclass
class DraggingPanGestureRecognizer: UIPanGestureRecognizer {
    var locationInViewWhenDraggingStarted = CGPoint.zero
    override func touchesBegan(_ touches: Set, with event: UIEvent) {
        super.touchesBegan(touches, with: event) 
        locationInViewWhenDragStarted = location(in: view)
    }
}

Finally, here is the client code showing how we can use the new service:

@IBAction func pan(_ recognizer: DraggingPanGestureRecognizer) {
    switch recognizer.state {
    case .began:
        let point = recognizer.locationInViewWhenDraggingStarted
        beginDragging(at: point)
    case .changed:
        let point = recognizer.location(in: recognizer.view)
        continueDragging(to: point)
    ...
    }
}

And/or if you need the similar implementation for macOS development (instead), i.e. inheriting from NSPanGestureRecognizer, here we go again (but note that the client code is exactly the same as above, so I won’t repeat that part below):

import AppKit
class DraggingPanGestureRecognizer: NSPanGestureRecognizer {
    var locationInViewWhenDraggingStarted = NSPoint.zero
    override func mouseDown(with event: NSEvent) {
        super.mouseDown(with: event)
        locationInViewWhenDraggingStarted = location(in: view)
    }
}

 

Posted in iOS | Tagged , , , , , , , | Leave a comment