{"id":33900004,"url":"https://github.com/nordicsemiconductor/ios-common-libraries","last_synced_at":"2026-02-05T15:01:43.187Z","repository":{"id":71991579,"uuid":"503760799","full_name":"NordicSemiconductor/IOS-Common-Libraries","owner":"NordicSemiconductor","description":"Shared code \u0026 resources used by Nordic Apps for Apple platforms.","archived":false,"fork":false,"pushed_at":"2026-01-06T14:15:50.000Z","size":584,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-19T15:11:10.035Z","etag":null,"topics":["ios","ipados","macos","swift","swiftui"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NordicSemiconductor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-06-15T12:43:18.000Z","updated_at":"2025-12-20T14:58:19.000Z","dependencies_parsed_at":"2025-12-12T02:07:55.259Z","dependency_job_id":null,"html_url":"https://github.com/NordicSemiconductor/IOS-Common-Libraries","commit_stats":null,"previous_names":["nordicsemiconductor/ios-common-libraries"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/NordicSemiconductor/IOS-Common-Libraries","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NordicSemiconductor%2FIOS-Common-Libraries","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NordicSemiconductor%2FIOS-Common-Libraries/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NordicSemiconductor%2FIOS-Common-Libraries/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NordicSemiconductor%2FIOS-Common-Libraries/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NordicSemiconductor","download_url":"https://codeload.github.com/NordicSemiconductor/IOS-Common-Libraries/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NordicSemiconductor%2FIOS-Common-Libraries/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29124793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T14:05:12.718Z","status":"ssl_error","status_checked_at":"2026-02-05T14:03:53.078Z","response_time":65,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","ipados","macos","swift","swiftui"],"created_at":"2025-12-11T22:55:24.912Z","updated_at":"2026-02-05T15:01:43.181Z","avatar_url":"https://github.com/NordicSemiconductor.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"60%\" src=\"https://raw.githubusercontent.com/NordicPlayground/IOS-Common-Libraries/main/Logo_RGB_Horizontal_Transparent.png\"\u003e\n\u003c/p\u003e\n\n# iOS-Common-Libraries\n\n![Swift](https://img.shields.io/badge/Swift-5.6-f05237.svg)\n![Platforms](https://img.shields.io/badge/Platforms-iOS%20|%20iPadOS%20|%20macOS-333333.svg)\n[![License](https://img.shields.io/github/license/NordicPlayground/IOS-Common-Libraries)](https://github.com/NordicPlayground/IOS-Common-Libraries/blob/main/LICENSE)\n[![Swift Package Manager](https://img.shields.io/badge/SwiftPM-Compatible-brightgreen)](https://swift.org/package-manager/)\n\nThis is a Swift Package containing Swift code and Utilities/Assets, such as Colors, used by Nordic's iOS/Mac apps.\n\n\u003e [!IMPORTANT]  \n\u003e This repository contains APIs and Utilities used by ourselves. Ones that we find useful to extend to the community, because most of it we've learned through you, so we owe it back to you. That being said, this repository should not be considered public-facing API. We reserve the right to modify any of the components shared here to fit our uses.\n\n## Contents\n\n### Views\n\n#### InlinePicker\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"60%\" src=\"https://raw.githubusercontent.com/NordicPlayground/IOS-Common-Libraries/main/inlinePicker.jpg\"\u003e\n\u003c/p\u003e\n\nThe main use case for this UI Component is to basically have an alternative of macOS' Segmented Control but for iOS, including iOS-derived platforms such as the Mac via Catalyst. It took a lot of setup to have a Picker that didn't \"push\" the UI and the user towards a new View, which we found can be very distracting. So we came up with `InlinePicker` View, and we didn't just use it in nRF Connect, it's also gone on to become a staple in other projects such as the Wi-Fi Provisioner App.\n\n#### PasswordField\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"60%\" src=\"https://raw.githubusercontent.com/NordicPlayground/IOS-Common-Libraries/main/passwordField.jpg\"\u003e\n\u003c/p\u003e\n\n\u003e [!NOTE]  \n\u003e The above screenshot is from nRF Edge Impulse, which is applying custom styling to PasswordField.\n\nnRF Edge Impulse was our team's first \"REST-based client\", let's say. As such, we had to handle networking and user account details. This included password input which, as we know, is handled by the existing ![SecureField](https://developer.apple.com/documentation/swiftui/securefield) component. But, to our surprise, there's no way to allow the user to explicitly see what they're typing. We could've just dismissed the issue, but even to us when using the app it was a big nuissance. So we wrote it, initially just for nRF Edge Impulse. And then a similar need arose for nRF Wi-Fi Provisioner. So we refactored it out, allowing nRF Edge Impulse to keep its UI design, but allowing it to look more system-like for nRF Wi-Fi Provisioner.\n\n#### FPSCounter\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"60%\" src=\"https://raw.githubusercontent.com/NordicPlayground/IOS-Common-Libraries/main/fpsCounter.jpeg\"\u003e\n\u003c/p\u003e\n\nFor nRF Connect, we rewrote the RSSI Graph from scratch, removing our dependency from the ![Charts framework we were using previously](https://github.com/ChartsOrg/Charts). In fact, it was in use even ![in the older, 1.x version of nRF Connect](https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/announcing-nrf-connect-2-0-for-ios). Regardless, we decided to move on to our own implementation, based on SwiftUI, which provided a big improvement in CPU / power use. We wanted to measure how efficient our code is, so we came up with an `FPSCounter`.\n\nIt's tricky to use, so here's a simplified version of the code we use in nRF Connect to measure the time the RSSI Graph takes to draw. \n\n\u003e [!CAUTION]\n\u003e This is our best-guess on how to implement such a thing. Obviously, we could be out-of-this-world wrong. If that's the case, we'd happy to listen and learn from you.\n\n```swift\nstruct YourView: View {\n\n    private let clock = ContinuousClock()\n    private var fps = FPSCounter()\n\n    var body: some View {\n        VStack {\n            \n            var childViewToMeasure: ChildViewType? = nil\n            let instant = clock.measure {\n                childViewToMeasure = ChildViewType()\n            }\n            \n            childViewToMeasure\n            \n            fps.countFrame(at: instant)\n        }\n    }\n}\n```\n\n#### PipelineView\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"60%\" src=\"https://raw.githubusercontent.com/NordicPlayground/IOS-Common-Libraries/main/pipeline.jpg\"\u003e\n\u003c/p\u003e\n\nThe process of deploying a ML model to a nRF5340-powered device, which is one of the things nRF Edge Impulse does, was very complicated. The user sets up parameters for the ML Model, we send the request to the Edge Impulse back-end, the back-end builds the firmware we need to deploy, we then download said firmware, and use our own ![Device Firmware Update Library](https://github.com/NordicSemiconductor/IOS-nRF-Connect-Device-Manager) to run it on the device. Making the user aware of all of the steps the app is doing, plus when and why it fails, was not easy. But we came up with a nice UI design we called 'the pipeline'. We then found ourselves in a similar situation when it came to nRF Wi-Fi Provisioner, which was unexpected. But we took the opportunity to make the pipeline components reusable, but also give ourselves some breathing space to allow each app to be able to customize it to their liking. \n\n### Colors\n\nThe swatch of Nordic colors is available here for our own use. We're keeping to the [DRY Principle](https://wiki.c2.com/?DontRepeatYourself) of course, but the side-benefit of this is that updating the colors in one place, automagically updates all of our apps.\n\nAdditionally, there are helper items here. We have `struct RGB` and `RGBA` structures so that 8-bit colors can be stored as a `UInt32` and thus helping memory consumption.\n\n### Utilities\n\n- `Cache`: Need to use `NSCache` with a pure-Swift `struct`? This is what this is for. Also, it's just John Sundell's work in a library that we use.\n- `BitField`: Alternative to an `enum` `Set` that allows us to store everything in a single CPU Register, both in memory and as a `Codable`.\n- `NordicLog`: Apple added `OSLog` as the [performance-oriented logging API](https://developer.apple.com/documentation/os/oslog) for their platforms back in 2018. We've since adopted it in nRF Connect for Mobile, and extended its use accross all apps. And what we found is that, we kept re-implementing the same set of APIs for logging everywhere. So we picked one implementation, and moved it here so that we can use it everywhere. Additionally, it supports not only OSLog APIs but also [performance-logging APIs](https://developer.apple.com/documentation/os/logging/recording_performance_data), allowing us to measure calls for performance.\n\n### Extensions\n\n- `Data`: There are helper functions here to handle bytes within a `Data` blob. This is code used by [nRF Connect for Mobile](https://apps.apple.com/es/app/nrf-connect-for-mobile/id1054362403) to read individual bytes from advertised BLE `Data`. The are functions to format `Data` as `String` as well.\n- `CGSize`: How is it that there's no Public API to initialise a size as a square!?\n- `Compression`: A long time ago, back in 2020, we wrote code to Compress/Decompress blobs of Data. This was a major benefit for nRF Connect for Mobile, which regularly saves its state via JSON Encode/Decode to disk. This allows for persistent User Settings, as well as the app \"remembering\" where the user was irrespective of if the app is killed in the background or not. Unfortunately, two years later, undergoing some testing a crucial API call for compression was removed. We found it thinking it was code that was not used and needing to be deleted, then wondered 'why isn't this being used?' and the answer was, a bad copy/paste back of previous code gone wrong. So nRF Connect for Mobile is back to using it, providing great benefits to [solid state endurance](https://arstechnica.com/information-technology/2012/06/inside-the-ssd-revolution-how-solid-state-disks-really-work/) to our customers. Hence, why it belongs here.\n\n## In Use By\n\nHere's a listing of the iOS/iPadOS/macOS Projects we at Nordic use this code in. Obviously since this is Open Source, you're free to use any of it as well. We're just highlighting here some of the products that have lead to the battle-testing of some of this code.\n\n- [x] `nRF Connect for Mobile`: [App Store](https://apps.apple.com/no/app/nrf-connect-for-mobile/id1054362403) [GitHub (not Open Source)](https://github.com/NordicSemiconductor/IOS-nRF-Connect)\n- [x] `nRF Edge Impulse`: [App Store](https://apps.apple.com/no/app/nrf-edge-impulse/id1557234087?l=nb) [GitHub](https://github.com/NordicSemiconductor/IOS-nRF-Edge-Impulse)\n- [x] `nRF Wi-Fi Provisioner`: [App Store](https://apps.apple.com/no/app/nrf-wi-fi-provisioner/id1638948698?platform=iphone) [GitHub](https://github.com/NordicSemiconductor/IOS-nRF-Wi-Fi-Provisioner)\n- [x] `nRF Toolbox`: [App Store](https://apps.apple.com/no/app/nrf-toolbox/id820906058) [GitHub](https://github.com/NordicSemiconductor/IOS-nRF-Toolbox)\n- [x] `nRF Memfault`: [App Store](https://apps.apple.com/no/app/nrf-memfault/id1641119282) [GitHub](https://github.com/NordicSemiconductor/IOS-Memfault-Library)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnordicsemiconductor%2Fios-common-libraries","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnordicsemiconductor%2Fios-common-libraries","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnordicsemiconductor%2Fios-common-libraries/lists"}