{"id":13907814,"url":"https://github.com/chojnac/NotionSwift","last_synced_at":"2025-07-18T06:31:29.233Z","repository":{"id":39602850,"uuid":"370060196","full_name":"chojnac/NotionSwift","owner":"chojnac","description":"Unofficial Notion API SDK for iOS \u0026 macOS","archived":false,"fork":false,"pushed_at":"2024-09-02T21:08:15.000Z","size":1036,"stargazers_count":135,"open_issues_count":4,"forks_count":33,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-11-22T15:06:16.455Z","etag":null,"topics":["ios","macos","notion","notion-api","sdk","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chojnac.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}},"created_at":"2021-05-23T13:27:35.000Z","updated_at":"2024-11-17T17:23:53.000Z","dependencies_parsed_at":"2024-06-11T21:59:48.838Z","dependency_job_id":"f784fb12-182b-4f9b-b64c-6cfb62c86664","html_url":"https://github.com/chojnac/NotionSwift","commit_stats":{"total_commits":75,"total_committers":9,"mean_commits":8.333333333333334,"dds":"0.19999999999999996","last_synced_commit":"b30b4591b45caca416d818683cadd0fc4d1cda3d"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chojnac%2FNotionSwift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chojnac%2FNotionSwift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chojnac%2FNotionSwift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chojnac%2FNotionSwift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chojnac","download_url":"https://codeload.github.com/chojnac/NotionSwift/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226361553,"owners_count":17612921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","macos","notion","notion-api","sdk","swift"],"created_at":"2024-08-06T23:02:11.389Z","updated_at":"2024-11-25T16:31:02.030Z","avatar_url":"https://github.com/chojnac.png","language":"Swift","funding_links":[],"categories":["HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"![](banner.png)\n# NotionSwift\n\nUnofficial [Notion](https://www.notion.so) SDK for iOS \u0026 macOS. \n\nThis is still work in progress version, the module interface might change.\n\n## API Documentation\n\nThis library is a client for the official Notion API. \nFor more details and documentation please check [Notion Developer Portal](https://developers.notion.com/)\n\n## Installation\n\n### CocoaPods\n\n```ruby\npod 'NotionSwift', '0.9.0'\n```\n\n### Swift Package Manager\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/chojnac/NotionSwift.git\", .upToNextMajor(from: \"0.9.0\"))\n]\n```\n\n## Usage\n\nCurrently, this library supports only the \"internal integration\" authorization mode. For more information about authorization and \ninstruction how to obtain `NOTION_TOKEN` please check [Notion Offical Documentation](https://developers.notion.com/docs/authorization).\n\n**Important:** Integrations are granted access to resources (pages and databases) which users have shared with the integration. Resources that are not shared with the integration are not visible by API endpoints. \n\n### Creating a Notion client\n\n```swift\n\nlet notion = NotionClient(accessKeyProvider: StringAccessKeyProvider(accessKey: \"{NOTION_TOKEN}\"))\n\n```\n\n### Tweak network configuration\n\nTo tweak things like network timeouts you can provide a custom `URLSessionConfiguration` to `NotionClient`  like below.\n\n```swift\n\nlet sessionConfig = URLSessionConfiguration.default\nsessionConfig.timeoutIntervalForRequest = 15\nlet notion = NotionClient(accessKeyProvider: StringAccessKeyProvider(accessKey: \"{NOTION_TOKEN}\"), sessionConfiguration: sessionConfig)\n\n```\n\nIf that's not enough for your needs, you can implement the `NetworkClient` protocol and provide your implementation to `NotionClient`.\n\n### List all databases\n\nThe `https://api.notion.com/v1/databases` is deprecated. To recommended way to list all databases is to use `https://api.notion.com/v1/search` endpoint. \nIn theory, search allows filtering results by object type. However, currently, the only filter allowed is `object` which will filter by type of object (either `page` or `database`)\nTo narrow search results,  use code snippet belove. \n\n```swift\n// fetch available databases\nnotion.search(request: .init(filter: .database)) { result in\n    let databases = result.map { objects in\n        objects.results.compactMap({ object -\u003e Database? in\n            if case .database(let db) = object {\n                return db\n            }\n            return nil\n        })\n    }\n    print(databases)\n}\n```\n\n### Query a database\n\nIn this example we will get all pages in the database. To narrow results use `params` argument.\n```swift\nlet databaseId = Database.Identifier(\"{DATABASE UUIDv4}\")\n\nnotion.databaseQuery(databaseId: databaseId) {\n    print($0)\n}\n```\n\n### Retrieve a database\n\n```swift\nlet databaseId = Database.Identifier(\"{DATABASE UUIDv4}\")\n\nnotion.database(databaseId: databaseId) {\n    print($0)\n}\n```\n\n### Create a database\n\n```swift\nlet parentPageId = Page.Identifier(\"e67db074-973a-4ddb-b397-66d3c75f9ec9\")\n\nlet request = DatabaseCreateRequest(\n    parent: .pageId(parentPageId),\n    icon: .emoji(\"🤔\"),\n    cover: .external(url: \"https://images.unsplash.com/photo-1606787366850-de6330128bfc\"),\n    title: [\n        .init(string: \"Created at: \\(Date())\")\n    ],\n    properties: [\n        \"Field 10\": .richText\n    ]\n)\n\nnotion.databaseCreate(request: request) {\n    print($0)\n}\n```\n\n### Update a database\n\n```swift\nlet id = Database.Identifier(\"{DATABASE UUIDv4}\")\n\n// update cover, icon \u0026 add a new field\nlet request = DatabaseUpdateRequest(\n    title: nil,\n    icon: .emoji(\"🤔\"),\n    cover: .external(url: \"https://images.unsplash.com/photo-1606787366850-de6330128bfc\"),\n    properties: [\n        \"Field 10\": .richText\n    ]\n)\n\nnotion.databaseUpdate(databaseId: id, request: request) {\n    print($0)\n}\n```\n\n### Create a database entry\n\nNotion database entries are pages, whose properties conform to the parent database's schema.\n\n```swift\nlet databaseId = Database.Identifier(\"{DATABASE UUIDv4}\")\n\nlet request = PageCreateRequest(\n    parent: .database(databaseId),\n    properties: [\n        \"title\": .init(\n            type: .title([\n                .init(string: \"Lorem ipsum \\(Date())\")\n            ])\n        ),\n        \"Field 10\": .init(\n            type: .richText([\n                .init(string: \"dolor sit amet\")\n            ])\n        )\n    ]\n)\n\nnotion.pageCreate(request: request) {\n    print($0)\n}\n```\n\n### Retrieve a page\n\nRetrieve page properties. \n\n```swift\nlet pageId = Page.Identifier(\"{PAGE UUIDv4}\")\n\nnotion.page(pageId: pageId) {\n    print($0)\n}\n```\n\nPage content (text for example) is represented as an array of blocks. The example below loads properties and page content. \n\n```swift\nlet pageId = Page.Identifier(\"{PAGE UUIDv4}\")\n\nnotion.page(pageId: pageId) { [notion] in\n    print(\"---- Properties ----- \")\n    print($0)\n    switch $0 {\n    case .success(let page):\n        notion.blockChildren(blockId: page.id.toBlockIdentifier) {\n            print(\"---- Children ----- \")\n            print($0)\n        }\n    default:\n        break\n    }\n}\n```\n**Note:** The API returns only the direct children of the page. If there is content nested in the block (nested lists for example) it requires other calls. \n\n### Create a page\n\n```swift\nlet parentPageId = Page.Identifier(\"{PAGE UUIDv4}\")\n\nlet request = PageCreateRequest(\n    parent: .page(parentPageId),\n    properties: [\n        \"title\": .init(\n            type: .title([\n                .init(string: \"Lorem ipsum \\(Date())\")\n            ])\n        )\n    ]\n)\n\nnotion.pageCreate(request: request) {\n    print($0)\n}\n```\n\n### Update page properties\n\n```swift\nlet pageId = Page.Identifier(\"{PAGE UUIDv4}\")\n\n// update title property\nlet request = PageUpdateRequest(\n    properties: [\n        .name(\"title\"): .init(\n            type: .title([\n                .init(string: \"Updated at: \\(Date())\")\n            ])\n        )\n    ]\n)\n\nnotion.pageUpdate(pageId: pageId, request: request) {\n    print($0)\n}\n```\n\n### Delete page \n\n```swift\nlet pageId = Page.Identifier(\"{PAGE UUIDv4}\")\n\n// Archive page (trash a page)\nlet request = PageUpdateRequest(archived: true)\n\nnotion.pageUpdate(pageId: pageId, request: request) {\n    print($0)\n}\n```\n\n### Retrieve block children\n\nNote: This endpoint returns only the first level of children, so for example, nested list items won't be returned. In that case, you need to make another request with the block id of the parent block.\n\n```swift\n\nlet pageId = Block.Identifier(\"{PAGE UUIDv4}\")\n\nnotion.blockChildren(blockId: pageId) {\n    print($0)\n}\n\n```\n\n### Append block children\n\n```swift\nlet pageId = Block.Identifier(\"{PAGE UUIDv4}\")\n\n// append paragraph with styled text to a page.\nlet blocks: [WriteBlock] = [\n    .heading1([\"Heading 1\"], color: .orange),\n    .paragraph([\n        \"Lorem ipsum dolor sit amet, \",\n        .init(string: \"consectetur\", annotations: .bold),\n        \" adipiscing elit.\"\n    ]),\n    .heading2([\"Heading 2\"], color: .orangeBackground),\n    .columnList(columns: [\n        .column([\n            .paragraph([\"Column 1\"])\n        ]),\n        .column([\n            .paragraph([\"Column 2\"])\n        ])\n    ]),\n    try! .table(\n        width: 2,\n        headers: [\n            [\"Header 1\"], [\"Header 2\"]\n        ],\n        rows: [\n            .row(\n                header: [\"Row 1 header\"],\n                cells: [\n                    [\"Cell 1-1\"], [\"Cell 1-2\"]\n                ]\n            ),\n            .row(\n                cells: [\n                    [\"Cell 2-1\"], [\"Cell 2-2\"]\n                ]\n            )\n        ]\n    )\n]\nnotion.blockAppend(blockId: pageId, children: blocks) {\n    print($0)\n}\n```\n\n### Update a block\n\n```swift\nlet blockId = Block.Identifier(\"{BLOCK UUIDv4}\")\nlet text: [RichText] = [\n    \"Current time: \",\n    .init(string: Date().description, annotations: .bold)\n]\nlet block = UpdateBlock(type: .paragraph(text: text))\nnotion.blockUpdate(blockId: blockId, value: block) {\n    print(\"Updated: \", $0)\n}\n```\n\n### Block delete\n\n```swift\nlet blockId = Block.Identifier(\"{BLOCK UUIDv4}\")\n\nnotion.blockDelete(blockId: block.id) {\n    print(\"Delete: \", $0)\n}\n```\n\n### Retrieve a user\n\n```swift\nlet id = User.Identifier(\"{USER UUIDv4}\")\nnotion.user(userId: id) {\n    print($0)\n}\n```\n\n### List all users\n```swift\nnotion.usersList() {\n    print($0)\n}\n```\n\n### Search\n\nSearch for pages \u0026 databases with a title containing text \"Lorem\"\n```swift\nnotion.search(\n    request: .init(\n        query: \"Lorem\"\n    )\n) {\n    print($0)\n}\n```\n\nSearch for all databases and ignore pages.\n```swift\nnotion.search(\n    request: .init(\n        filter: .database\n    )\n) {\n    print($0)\n}\n```\n\nGet all pages \u0026 databases\n```swift\nnotion.search() {\n    print($0)\n}\n```\n\n### Logging and debugging\n\n`NotionSwift` provide an internal rudimental logging system to track HTTP traffic. \nTo enable it you need to set a build-in or custom logger handler and decide about log level (`.info` by default).\nWith `.track` log level you can see all content of a request. This is useful to track mapping issues between library data models and API.\n\n\nExample logging configuration:\n```swift\n// This code should be in the ApplicationDelegate\n\nNotionSwiftEnvironment.logHandler = NotionSwift.PrintLogHandler() // uses print command\nNotionSwiftEnvironment.logLevel = .trace // show me everything\n\n```\n\n## License\n\n**NotionSwift** is available under the MIT license. See the [LICENSE](https://github.com/chojnac/NotionSwift/blob/master/LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchojnac%2FNotionSwift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchojnac%2FNotionSwift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchojnac%2FNotionSwift/lists"}