Latest 3.0.0
Homepage https://github.com/allen-zeng/SweetNotifications
License MIT
Platforms ios 9.0, osx 10.10, watchos 2.0, tvos 9.0, requires ARC
Authors

The NotificationCenter is a very useful tool. But using the API in Foundation is verbose and driven entirely by strings and values typed Any. Using these values every time a notification is needed is just awkward.

Using generics in Swift, we can make this much nicer, so we can focus on using the contents of a strongly typed notification.

Quick Start

Install via CocoaPods

pod 'SweetNotifications'

UIKeyboard notifications

UIKeyboard notifications are incorporated under the subspec SweetNotifications/UIKeyboard. The 4 types of notifications are:

  • UIKeyboardWillShowNotification
  • UIKeyboardDidShowNotification
  • UIKeyboardWillHideNotification
  • UIKeyboardDidHideNotification

Take UIKeyboardWillShowNotification as an example, to register:

listener = NotificationCenter.default.watch { (notification: UIKeyboardWillShowNotification) in
    print(notification.frameBegin)
    print(notification.frameEnd)
    print(notification.animationDuration)
    print(notification.animationOption)
    print(notification.isCurrentApp)
}

Don’t forget to deregister later:

NotificationCenter.default.removeObserver(listener)

Note: Support for self registration coming soon

Listening for named events only

There are notifications that don’t contain a userInfo dictionary. In those situations we can simply watch for the named events:

listener = NotificationCenter.default.watch(for: Notification.Name.UIApplicationWillTerminate) {
    // save all the important things!
}

As of this moment, manual deregistration is still required.

Custom notification types

It’s easy to write your own notification types by adopting SweetNotification:

struct ValueChangedNotification: SweetNotification {
    let source: Source

    init(userInfo: [AnyHashable: Any]) throws {
        guard let sourceString = userInfo["source"] as? String else {
            throw SerializationError.missingSource
        }

        switch userInfo["source"] as? String {
        case "API"?:
            source = .api
        case "local"?:
            source = .local
        default:
            throw SerializationError.unknownSource(userInfo["source"] as? String ?? "<Not a string>")
        }
    }

    init(source: Source) {
        self.source = source
    }

    func toUserInfo() -> [AnyHashable: Any]? {
        switch source {
        case .api:
            return ["source": "API"]
        case .local
            return ["source": "local"]
        }
    }

    enum Source {
        case api, local
    }
}

Posting custom notifications

It’s all type safe again :)

let valueChangedNotification = ValueChangedNotification(source: .api)
NotificationCenter.default.post(valueChangedNotification)

Unit testing

Testing custom notifications is very straight forward:

func testInitWithUserInfo_sourceStringIsValid_sourceSetCorrectly() {
    let expectedPairs: [String: ValueChangedNotification.Source] = ["API": .api, "local": .local]

    for (sourceString, expectedSource) in expectedPairs {
        let userInfo: [String: String] = ["source": sourceString]

        do {
            let notification = try ValueChangedNotification(userInfo: userInfo)
            XCTAssertEqual(expectedSource, notification.source)
        } catch {
            XCTFail("Unexpected failure: (error)")
        }
    }
}

Roadmap

  • [x] add global error handler
  • [x] add keyboard notifications types
  • [x] auto-deregistration of listeners
  • [x] cross platform support
  • [ ] CI
  • [ ] Carthage and SPM support(?)

Latest podspec

{
    "name": "SweetNotifications",
    "version": "3.0.0",
    "summary": "Serializable notifications for iOS Notification Center",
    "description": "Do away with Notification Center's weak stringly typed API.",
    "homepage": "https://github.com/allen-zeng/SweetNotifications",
    "license": "MIT",
    "authors": {
        "Allen Zeng": "allenzeng@outlook.com"
    },
    "source": {
        "git": "https://github.com/allen-zeng/SweetNotifications.git",
        "tag": "3.0.0"
    },
    "platforms": {
        "ios": "9.0",
        "osx": "10.10",
        "watchos": "2.0",
        "tvos": "9.0"
    },
    "requires_arc": true,
    "pushed_with_swift_version": "3.0",
    "subspecs": [
        {
            "name": "Core",
            "source_files": "SweetNotifications/*.swift",
            "frameworks": "Foundation"
        },
        {
            "name": "UIKeyboard",
            "ios": {
                "source_files": "SweetNotifications/UIKeyboardNotifications/*.swift",
                "frameworks": "UIKit"
            },
            "dependencies": {
                "SweetNotifications/Core": []
            }
        }
    ]
}

Pin It on Pinterest

Share This