Drag gesture recognizer for iOS development (with initial touch 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 – but it’s annoying, and not the way NSPanGestureRecognizer works with mouse events in macOS Cocoa development.)

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 initialLocationInView 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!
    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)
    ...
    }
}

 

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

Creating great products requires outstanding functional design

(I’ve recently twitted two examples, but I think it the idea deserves a more general blog post, so here we go.)

It’s not enough to be an outstanding developer to be able to create great software (that sells). You need to also be:

  • good at defining the problem(s) that are to be solved – so that you don’t develop something that’s not needed;
  • good at selecting the correct technical architecture for your code – to ensure everything will eventually work great at runtime;
  • but also exceptional at designing for the real end user – so people get actually in love with your app(s) and are captured under your ecosystem for the long term (and if things go viral you won’t even need to pay for ads to sell your creation at large!)

While for an experienced engineer the first two roles are easier to combine (although not always the best thing to do), in my opinion the third one should better be delegated to somebody else who doesn’t do hands-on development himself or herself.

Because (I think) most people are either technical or functional oriented, and technical persons rarely come up with outstanding functional ideas (like, for example, those features that I’ve recently twitted about.)

Dear developer, you need a partner! Dear functional designer, accept a developer. 🙂

close up of beer glass against colored background

Photo by Pixabay on Pexels.com

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

Delaying (?) unit testing

close up photography of eyeglasses near crumpled papers

Photo by Steve Johnson on Pexels.com

It happens: even if you have clear functional requirements and good architecture from the beginning of a project, sometimes (and often) the code that you initially wrote to develop a specific feature (or an infrastructural aspect) will end up deeply refactored (or rewritten from scratch), possibly more than once. And you may know this all along!

Don’t worry, everything is absolutely fine: it’s in the developer’s [human] nature!

But – ouch! – what if you have already unit tested the code that is being dramatically refactored? Such tests (together with all hours spent on them) are going straight to trash!

@TDD lovers, sorry, I know this hurts. You may argue that test refactoring shouldn’t be needed at all, or at least it could have been done before even writing the first line of the main service (if we’d only followed all rules – and finished version 1 of our product after competition launched version 3?!). But let’s wake up from dreaming; the world is not perfect: so often we want to change the code from inside out, starting with the core and disregarding tests for that moment (I know, we’re bad); and then tests need to be refactored afterwards, and unfortunately that might be harder than writing brand new ones for the updated sheet later (should that word be with an i?)

@All, now don’t get me wrong, though: unit testing is not bad itself! (It must be good, since everybody’s doing it.) 🙂

Indeed, unit testing is an exceptional tool that tremendously helps developers: it allows us to verify and really improve the quality of our code by simply obliging us to think from the client’s perspective and to prove that our code is doing the right thing for them.

But in my opinion, we shouldn’t be required to do it immediately: for example, when we write code for a new class that is part of a larger architecture, we shouldn’t always continue with writing unit tests for it; instead, I think it’s better to complete the code for an entire bunch of classes that work together, providing a complete functional (or technical) aspect of the system (even when those classes themselves combine into more than a single testable unit), and only then to start unit testing for the pieces. Simply because “breaking” things like refactoring happen all the time, but especially in the meantime.

analogue classic clock clock face

Photo by Pixabay on Pexels.com

Note that the developer should still consider unit testing as eventually mandatory, but delaying it could win time (and money) for him/her, his/her team, and the stakeholders.

What is important, though, is to know when to delay writing unit tests (i.e. when is code likely to be further refactored?) and for how long to delay it without generating more issues than solving (i.e. when is code becoming likely to remain unchanged?)

people woman glass lens

Photo by Public Domain Pictures on Pexels.com

All these are up to you, of course, and the required skills will improve with experience. But the idea is just to not be too rigid about unit testing timing, but only about doing it.

(In some teams, this might require a high level of flexibility: for example, if code reviews are done per commit, the reviewer might ask you to do unit testing right away; the team could discuss this, and – upon consensus – change the flow to accept delayed code reviews as well, e.g. reviewing code at feature level rather than doing it for each work item.)

And if I may, I want to suggest something: to ensure you do not forget about the tests that must be eventually written, you can maintain a simple list of all newly added entities (for which you want to delay unit testing), and periodically check it to see what tests you feel should be finally added, and for which items you should better wait a little longer.

orange and green pen on graphing notepad

Photo by freestocks.org on Pexels.com

Posted in Development | Tagged , , | Leave a comment

Mocking “this”

Let’s assume we have a simple service that is also using an inner service, providing a few operations as follows:

public interface IService
{
    string A();
    string B();
    string C();
}

public class Service : IService
{
    private readonly IInnerService innerService;
    public Service(IInnerService innerService)
    {
        this.innerService = innerService;
    }

    public string A()
    {
        return "A";
    }
    public string B()
    {
        return b();
    }
    public string C()
    {
        return innerService.C();
    }
    private string b()
    {
        return "b";
    }
}

public interface IInnerService
{
    string C();
}

public class InnerService : IInnerService
{
    public string C()
    {
        return "InnerC";
    }
}

To unit test the main service, we would probably do something like this:

  • Define a mock for the inner service interface (IInnerService);
  • Create an instance of the main service class (Service) to test;
  • Define test methods to check the main service’s functionality (of course, in isolation of the inner service’s real implementation):
[TestClass]
public class ServiceUnitTests
{
    private Service service;
    private InnerServiceMock innerServiceMock;

    [TestMethod]
    public void AReturnsA()
    {
        SetupInnerServiceMock();
        SetupService();
        var result = service.A();
        Assert.AreEqual("A", result);
    }
    [TestMethod]
    public void BReturnsB()
    {
        SetupInnerServiceMock();
        SetupService();
        var result = service.B();
        Assert.AreEqual("b", result);
    }
    [TestMethod]
    public void CCallsInnerC()
    {
        SetupInnerServiceMock();
        SetupService();
        var result = service.C();
        Assert.IsTrue(innerServiceMock.WasCCalled);
    }
    [TestMethod]
    public void CReturnsWhatInnerCReturns()
    {
        SetupInnerServiceMock();
        SetupService();
        var result = service.C();
        Assert.AreEqual("MockC", result);
    }

    private void SetupInnerServiceMock()
    {
        innerServiceMock = new InnerServiceMock();
    }
    private void SetupService()
    {
        service = new Service(innerServiceMock);
    }
}

class InnerServiceMock : IInnerService
{
    public bool WasCCalled { get; private set; }
    public string C()
    {
        WasCCalled = true;
        return "MockC";
    }
}

In the example above, we first test that A directly returns what is expected (i.e. “A”). Then we check that B returns what the private method that it internally calls returns (i.e. “b”), because – of course – we want to test the public service interface, not the private methods. Finally we check that method C of the main service class calls the inner service and that it returns whatever that returns (“MockC”, since we use a mock instance).

As you can see, the tests for C are performed in true isolation from the actual InnerService implementation – which is assumed to have its own unit tests – by using a mock. (Of course, we could have used a mock framework, like Moq, instead of a defining a custom class for this purpose, but for now let’s say we want to do it “by hand”.) Now the fun part: what if we want to add one more method to main service implementation: A2, returning whatever A returns (“A”) plus “2”:

public string A()
{
    return A() + "2";
}

How can we unit test this properly? In a sense, A2 is like B, i.e. it calls another method of the service class (although a public one this time, A). We could therefore simply test that A2 returns “A2” string. But thinking a bit more (and looking from a different perspective), we should see it’s not good enough: we might want to ensure that a single unit test would fail if A implementation changes (and not two). And, of course, to not test the same thing – the “A” part of the output string – twice (the first one is in the original A method test, which remains needed). How can we achieve these goals?

One way would be to define an A implementation within the inner service, or extract an (other) inner service with it – like we have for method C – and then call that method both from A and A2 in the main class, and refactor tests accordingly.

This is what I see many developers do in real projects. However, I always felt this is a little too much to do for very little benefit. (Indeed, in real projects it’s not about functions that simply return strings, generating no side effects like in our demo here.)

From my point of view moving A to an inner service seems like an unnecessary or at least a strange thing to do (at least in case our only reason would be to increase testability).

One first possibly better solution could be to redefine the service to use… itself (selfService field below) and then to test accordingly by mocking the service interface as we would do for another (“normal”) inner service:

public class Service : IService
{
    private readonly IInnerService innerService;
    private readonly IService selfService;

    public Service(IInnerService innerService,
                   IService selfService = null)
    {
        this.innerService = innerService;
        this.selfService = selfService ?? this;
    }
    ...
    public string A2()
    {
        return selfService.A() + "2";
    }
}

[TestClass]
public class ServiceUnitTests
{
    private Service service;
    private InnerServiceMock innerServiceMock;
    private ServiceMock serviceMock;
    ...
    [TestMethod]
    public void A2CallsA()
    {
        SetupInnerServiceMock();
        SetupServiceMock();
        SetupService();
        var result = service.A2();
        Assert.IsTrue(serviceMock.WasACalled);
    }
    [TestMethod]
    public void A2ReturnsWhatAReturnsPlus2()
    {
        SetupInnerServiceMock();
        SetupServiceMock();
        SetupService();
        var result = service.A2();
        Assert.AreEqual("MockA" + "2", result);
    }
    ...
    private void SetupServiceMock()
    {
        serviceMock = new ServiceMock();
    }
    private void SetupService()
    {
        service = new Service(innerServiceMock, serviceMock);
    }
}

...
class ServiceMock : IService
{
    public bool WasACalled { get; private set; }
    public string A()
    {
        WasACalled = true;
        return "MockA";
    }
    public string B() { throw new NotImplementedException(); }
    public string C() { throw new NotImplementedException(); }
    public string A2() { throw new NotImplementedException(); }
}

But I don’t like this solution too much, either. I just doesn’t feel like the greatest one. Does anyone else have a better idea?

It seems Moq offers an alternative: we can use a partial mock for the service if we just design our A method to be virtual, i.e. override-able in our mock class (that’s OK most of the times), and then, when testing A2, we can simply setup the mock to return a custom value, while other times it could call the base class instead.

In my opinion, this feels a little awkward too but the solution is a little more elegant. This is the updated service class (restarting from the initial version, without selfService):

public virtual string A()
{
    return "A";
}

And these updates are for the test class:

private Service service;
private Mock innerServiceMock;
private Mock serviceMock;
...
[TestMethod]
public void A2CallsA()
{
    SetupInnerServiceMock();
    SetupServiceMock();
    SetupService();
    var result = service.A2();
    serviceMock.Verify(m => m.A());
}
[TestMethod]
public void A2ReturnsWhatAReturnsPlus2()
{
    SetupInnerServiceMock();
    SetupServiceMock();
    SetupService();
    var result = service.A2();
    Assert.AreEqual("MockA" + "2", result);
}
...
private void SetupServiceMock()
{
    serviceMock = new Mock(innerServiceMock)
                  { CallBase = true };
    serviceMock.Setup(m => m.A()).Returns("MockA");
}
private void SetupService()
{
    service = serviceMock ?? new Service(innerServiceMock);
}

The serviceMock instance above (of type Mock, not a mock of IService interface) is also a Service itself so it can be used in both contexts: as the tested object and as a mock (that the tested object calls for methods not defined with Setup calls to return mock values).

We can learn from this approach and even if we don’t want to use Moq (but to manually create our partial mocks), we can do it with more ease than by self-aggregating, with some help from plain old inheritance (assuming method A remains virtual, though, and that the service class is still not marked as sealed).

Here is the final solution that I managed to obtain. (If you have an even better one, don’t hesitate to join into the discussion, i.e. add a comment below. The same if you just want to let us know which solution you like the most: this one or that with aggregation?)

[TestClass]
public class ServiceUnitTests
{
    private Service service;
    private InnerServiceMock innerServiceMock;
    private ServiceMock serviceMock;
    ...
    [TestMethod]
    public void AReturnsA()
    {
        SetupInnerServiceMock();
        SetupService(); // SetupServiceMock not called here!
        var result = service.A();
        Assert.AreEqual("A", result);
    }
    ...
    [TestMethod]
    public void A2CallsA()
    {
        SetupInnerServiceMock();
        SetupServiceMock();
        SetupService();
        var result = service.A2();
        Assert.IsTrue(serviceMock.WasACalled);
    }
    [TestMethod]
    public void A2ReturnsWhatAReturnsPlus2()
    {
        SetupInnerServiceMock();
        SetupServiceMock();
        SetupService();
        var result = service.A2();
        Assert.AreEqual("MockA" + "2", result);
    }
    ...
    private void SetupServiceMock()
    {
        serviceMock = new ServiceMock(innerServiceMock);
    }
    private void SetupService()
    {
        service = serviceMock ?? new Service(innerServiceMock);
    }
}

...
class ServiceMock : Service
{
    public ServiceMock(IInnerService innerService)
        : base(innerService) { }

    public bool WasACalled { get; private set; }
    public override string A()
    {
        WasACalled = true;
        return "MockA";
    }
}
Posted in .NET, C# | Tagged , , , | Leave a comment

Testing Swift deinit

As you probably know, Swift uses ARC for memory management (presumably to improve performance over classic garbage collection based systems).

That means it is very important that you do use weak (or unowned) references whenever cycles could form. For example, when you implement the multi-delegate pattern to simulate event raising, e.g. to notify observers when things change at your service level:

func addDelegate(_ newDelegate: ServiceDelegate) {
    delegates.append(Delegate(object: newDelegate))
}
private var delegates = [Delegate]()
private struct Delegate {
    weak var object: ServiceDelegate?
}
private func somethingWasDone(_ information: String) {
    for delegate in delegates {
        delegate.object?.somethingWasDone(self, information)
    }
}
deinit {
    print("Deinitializing service")
}

To check that the weak var is doing its job you probably want to run a test for your service’s deinit from time to time (having a Client instance created and then deinitialized, but referencing the service in the meantime and also adding itself as a service delegate there to attempt creating a reference cycle):

func run() {
    let service = Service()
    let client = Client(subscribingTo: service)
    service.doSomething()
    client.doMore()
}
run()

You cannot be happier when you see the magic string (“Deinitializing service”) in the output window if you run the code above in a playground. Moreover, if you temporarily remove the weak keyword and rerun the test, you don’t see the string anymore, which is equally great.

It will be a short term joy, however, because checking the output every time is not a brilliant solution, is it? You surely want to automatize the testing process (at least for the first check.) And you think about writing a unit test for deinit. But (how) can you do it?

Here is a possible solution if you use XCTest framework (as simple as I could get it):

import XCTest
@testable import MyFramework

class Tests {
    ...
    func testDeinit() {
        let _ = Client(subscribingTo: ServiceInstance())
        XCTAssertEqual(ServiceInstance.count, 0)
    }
    class ServiceInstance: Service {
        static var count: Int = 0
        init() {
            ServiceInstance.count += 1
        }
        deinit {
            ServiceInstance.count -= 1
        }
    }
    class Client: ServiceDelegate {
        init(subscribingTo object: ServiceObject) {
            self.object = object
            object.addDelegate(self)
        }
        let object: ScheduleDefinitionObject
        func somethingWasDone(_ object: ScheduleDefinitionObject,
                              _ information: String) { }
}

The idea is to create a ServiceInstance class inheriting from Service, supplementary maintaining a static count of the initialized and not yet deinitialized instance objects, and then create and host a service instance within a Client object (that is set up also as a delegate for the service), eventually checking the reference count after letting both the client and service go away.

As the count is finally zero (assuming that we kept the weak var within service’s Delegate struct) the test passes and we’re safe. Otherwise (such as if we temporarily remove that weak keyword) the test won’t pass and we’d know we have a problem.

Now this is finally something that makes us the happiest developers in the world! 🙂

Note that inheriting from Service class is possible because the @testing attribute of import MyFramework at the top makes classes from MyFramework available in the testing module as if they were defined there, so you can even inherit from them. (This is something that is not written in clear in documentation – there it’s indicated just that classes from the imported framework get available for testing as if they were defined as public – but I’ve tested with inheritance and it works as expected as well!)

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

Swift impressions

adult art artist blur

Photo by rawpixel.com on Pexels.com

After about one year of (intermittently) learning Swift and recently also using the language in a (hopefully) real project, I can conclude that it is very powerful, yet clean, easy to read and understand (that is important!), and does an exceptional job on preventing human errors (i.e. avoiding common programming mistakes.)

Coming from the C# world, I really appreciate these nice features that it offers:

  • Argument labels (secondary, client-side call names);
  • Protocol extensions;
  • Value typed collections;
  • Lazy and willSet/didSet for stored properties;
  • Implicitly unwrapped optionals;
  • Associated values (of different types) on enums;
  • Ranges;
  • Constants initialized by computing runtime values;
  • Construction (init) rules.

Of course, there are some things that I don’t like, though:

But there is also one thing that I don’t know where to add:

  • Accepting @escaping closures in APIs (considering Swift‘s ARC context).

While supporting functional style programming is great, closures being a powerful way to express client logic that API services sometimes need, optionally escaping them out of the context they are initialized into, this concept doesn’t seem to fit well with the memory management system that Swift uses: Automatic Reference Counting (ARC), otherwise simple and beautiful itself too.

Specifically, to avoid memory leaks in your software, ARC requires that you use weak or unowned references when cycles would form. And since an @escaping closure that uses a client’s self implicitly (and which you don’t want to discard at the service level) is a perfect example of such an unwanted cycle, the language itself requires writing “self.” when accessing local fields within the closure (i.e. on the client side) to ensure some awareness on self being actually captured (and potentially escaping).

But still, the reference cycle isn’t broken if the client doesn’t specifically set a weak or unowned self capture by hand. And if you as the service developer would really want to avoid memory issues caused by cycles that involves your code, you need to jump back from the modern functional approach that you had initially envisioned to the old OOP-based style which would require your client to implement a protocol instead. What an intellectual waste, isn’t it? 😉

So I personally think that the biggest flaw of Swift – at least of the current version – is around closures. And I look forward to see the future language updates; I really hope that the issues can be properly resolved, eventually.

Finally, an unrelated thought, just for fun: since (unlike C#Swift doesn’t require enclosing if (and while) expressions between parentheses, but obviously expressions themselves do accept extra parentheses without generating any warnings, I often write ifs like this:

if (expression) {
    ...
}

So I need to periodically run searches for “if (” (and “while (“) to remove the unneeded characters there just to ensure my code is… more swifty. Do you do this too? 🙂

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

Why I love Swift protocol extensions

black and white blank challenge connect

Photo by Pixabay on Pexels.com

Let’s develop a small framework, allowing client developers to use working schedule objects. Each schedule would be based on an interval of days: from a start day to a finish day (specified by numbers).

Optionally, client developers may configure specific days to be excluded from the working interval. Exclusion of day can be set either as an array or programatically by providing a predicate function.

Client developers would afterwards be able to obtain the day count for any schedule object that they have defined.

We don’t want client developers to need to pass a closure for excluding days because it would be necessarily @escaping (as it would be required when computing day count) and they should ensure they don’t forget to capture self as an unowned var within for their function body to avoid memory leaks (and some developers might not be aware of this and/or may have a difficult time doing it in the right way.) We don’t want to use weak container alternatives either, as explained below, because that would clutter the client side syntax too. But enough intro, I guess. Let’s start.

We’ll first provide a protocol that anyone could implement, even as a simple struct.

public protocol ScheduleObject {
    var startDay: Int { get }
    var finishDay: Int { get }
    func excluding(day: Int) -> Bool
}

Then, we can also provide a base class that defines fields for start and finish day, and further allows overriding the exclusion function only, for the client developer to have an easier start. (Usually we run away from inheritance but in my opinion here it has a good use.)

open class ScheduleBase: ScheduleObject {
    public init(startDay: Int, finishDay: Int) {
        self.startDay = startDay
        self.finishDay = finishDay
    }
    public var startDay, finishDay: Int
    open func excluding(day: Int) -> Bool {
        return false
    }
    
    deinit {
        print("ScheduleBase deinitialized")
    }
}

We can also offer an implementation that handles the exclusion by checking an optional array of excluded days, for the situation when the client developer already a-priori knows all excluded days.

public class Schedule: ScheduleBase {
    public init(startDay: Int, finishDay: Int,
                excludingDays: [Int] = []) {
        self.excludingDays = excludingDays
        super.init(startDay: startDay, finishDay: finishDay)
    }
    public var excludingDays: [Int]
    public override func excluding(day: Int) -> Bool {
        return excludingDays.contains(day)
    }
}

At this point, we might think that we could also allow client developers to use a struct with excluder closure; being a value type, there is no problem if their excluder definition uses self inside the code, right? Um… wrong! The closure is a reference type and if it captures a reference typed self from the client app it would create a reference cycle too! In my opinion, it’s easier to just let the developer define a plain old class/struct and OOP-ish overriding/implementing our function instead. (The struct is provided here just as an example of what it would mean on client side, thus the name.)

public struct BadScheduleStruct: ScheduleObject {
    public init(startDay: Int, finishDay: Int,
                excluder: @escaping (Int) -> Bool) {
        self.startDay = startDay
        self.finishDay = finishDay
        self.excluder = excluder
    }
    public var startDay, finishDay: Int
    public var excluder: (Int) -> Bool
    public func excluding(day: Int) -> Bool {
        return excluder(day)
    }
}

Furthermore, if we’d want to reuse the start day and finish fields that ScheduleBase offers, and any other logic we’d want to add to the base later (such as the computing of day count that was requested in the first place and which you might have aleady considered as candidate there), while still allowing client developers to use an excluder closure, it won’t work that smooth, we’d need a class to do inheritance! And still require @escaping closure and unowned self capture on client side. So I think we’d better not add this class to our framework either. (Again, it is provided here just as an example of what it would mean on client side, thus the name.)

public class BadScheduleClass: ScheduleBase {
    public init(startDay: Int, finishDay: Int,
                excluder: @escaping (Int) -> Bool) {
        self.excluder = excluder
        super.init(startDay: startDay, finishDay: finishDay)
    }
    public var excluder: (Int) -> Bool
    public override func excluding(day: Int) -> Bool {
        return excluder(day)
    }
    
    deinit {
        print("BadScheduleClass deinitialized")
    }
}

Anyway, we need to make sure that all schedule objects (our own Schedule class, Bad* types, classes defined by the client developer as inheriting from ScheduleBase, or simply types implementing the original ScheduleObject protocol), would somehow all support computing of the day counts: because it was in the requirements! 🙂

We could think about creating a new class – ScheduleComputer or whatever – to do this, initializing it with an instance of ScheduleObject. But there is a more simple solution! You don’t need a new class if you’re not going to store any new field! Protocol extensions can help us here instead! Usually extensions are needed when you have no access to the base type source code, but this time their use case is within the same framework!

This is why I absolutely love them!

public extension ScheduleObject {
    public var dayCount: Int {
        var count = 0
        for day in startDay...finishDay {
            if !excluding(day: day) {
                count += 1
            }
        }
        return count
    }
}

The framework is now complete! So let’s see the how the client side could look like. Here are 6 ways that client developers could use our framework, depending on their app requirements and/or personal preferences – the first 4 without needing any closures or [unowned self] captures.

We start with the safe ways for client developers. First 2 examples (schedule1 and -2) use Schedule class already provided by framework. The following 2 examples (-3 and -4) use custom class or struct, defined below (i.e. by the client app). Finally, the last 2 examples (-5 and -6) use closures and Bad* struct and class provided by the framework for example purposes only (but that I advise not to include in production frameworks). To demonstrate, feel free to remove each “[unowned self]” below separately, to see that at runtime the expected “App deinitialized” won’t be displayed anymore, regardless of which one you remove, i.e. the deinit of ClientApp isn’t called anymore, generating a memory leak!

class ClientApp {
    init() {
        schedule1 = Schedule(startDay: 2, finishDay: 17)
        schedule2 = Schedule(startDay: 2, finishDay: 17,
                             excludingDays: [4, 7])

        schedule3 = CustomClassSchedule(startDay: 1, finishDay: 16)
        schedule4 = CustomStructSchedule(startDay: 1, finishDay: 16)

        schedule5 = BadScheduleStruct(startDay: 1, finishDay: 16)
            { [unowned self] day in day % self.mod == 0 }
        schedule6 = BadScheduleClass(startDay: 1, finishDay: 16)
            { [unowned self] day in day % self.mod == 0 }
    }

    func run() {
        print("schedule1.dayCount:", schedule1!.dayCount)
        print("schedule2.dayCount:", schedule2!.dayCount)
        print("schedule3.dayCount:", schedule3!.dayCount)
        print("schedule4.dayCount:", schedule4!.dayCount)
        print("schedule5.dayCount:", schedule5!.dayCount)
        print("schedule6.dayCount:", schedule6!.dayCount)
    }
    
    var schedule1, schedule2, schedule3,
        schedule4, schedule5, schedule6: ScheduleObject?
    
    class CustomClassSchedule: ScheduleBase {
        public override init(startDay: Int, finishDay: Int) {
            super.init(startDay: startDay, finishDay: finishDay)
        }
        public override func excluding(day: Int) -> Bool {
            return day % 2 == 0
        }
    }
    struct CustomStructSchedule: ScheduleObject {
        var startDay, finishDay: Int
        func excluding(day: Int) -> Bool {
            return day % 3 == 0
        }
    }
    
    let mod: Int = 4
    
    deinit {
        print("App deinitialized")
    }
}

ClientApp().run()
Posted in iOS, macOS, Swift | Tagged , , , , , | Leave a comment