{"id":20936212,"url":"https://github.com/adzerk/adzerk-ios-sdk","last_synced_at":"2026-02-23T18:17:21.877Z","repository":{"id":36016496,"uuid":"40311155","full_name":"adzerk/adzerk-ios-sdk","owner":"adzerk","description":"Access Adzerk's ad serving APIs via iOS","archived":false,"fork":false,"pushed_at":"2026-02-05T19:53:12.000Z","size":402646,"stargazers_count":9,"open_issues_count":0,"forks_count":5,"subscribers_count":37,"default_branch":"master","last_synced_at":"2026-02-19T13:57:11.436Z","etag":null,"topics":["management","non-prod"],"latest_commit_sha":null,"homepage":"https://www.adzerk.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adzerk.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":"2015-08-06T15:05:27.000Z","updated_at":"2026-02-16T14:01:03.000Z","dependencies_parsed_at":"2024-11-18T22:18:57.015Z","dependency_job_id":"3523fa14-21ad-4af9-9915-19d9437b0ef4","html_url":"https://github.com/adzerk/adzerk-ios-sdk","commit_stats":{"total_commits":240,"total_committers":12,"mean_commits":20.0,"dds":"0.21250000000000002","last_synced_commit":"acb52f777652aaaaa615ba3b6c89100629c70e12"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/adzerk/adzerk-ios-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adzerk%2Fadzerk-ios-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adzerk%2Fadzerk-ios-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adzerk%2Fadzerk-ios-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adzerk%2Fadzerk-ios-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adzerk","download_url":"https://codeload.github.com/adzerk/adzerk-ios-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adzerk%2Fadzerk-ios-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29750197,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"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":["management","non-prod"],"created_at":"2024-11-18T22:18:24.407Z","updated_at":"2026-02-23T18:17:21.867Z","avatar_url":"https://github.com/adzerk.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# adzerk-ios-sdk\n\n## Requirements\n\nUse of the Adzerk iOS SDK requires iOS 10.0 or later.\n\n## Installation\n\nInstallation of the framework can be done manually by building and copying the framework into your project, or with automatically with Swift Package Manager (preferred), Carthage, or CocoaPods.\n\nNote that for manual and Carthage framework imports you may have to specify \"Embedded Content Contains Swift Code\" to avoid getting a linker error during build. Another way to force Xcode to load the Swift libraries is to add a single Swift source file to your project.\n\n### Swift Package Manager\n\nUsing Xcode, add a Swift Package in the Project Settings tab. Enter the URL https://github.com/adzerk/adzerk-ios-sdk.git and click Next. Choose your version and click continue to integrate it.\n\n### Carthage\n\nIf you're using [Carthage](https://github.com/Carthage/Carthage), add this to your `Cartfile`:\n\n```ruby\ngithub \"adzerk/adzerk-ios-sdk\" ~\u003e 2.3.2\n```\n\nIf you want to be on the bleeding edge, you can specify the `master` branch:\n\n```ruby\ngithub \"adzerk/adzerk-ios-sdk\" \"master\"\n```\n\nThen run `carthage update` to fetch and build the framework. You can find the framework in the `Carthage` folder, and you can add\nthis to your project manually.\n\n### CocoaPods\n\nIf you're using [CocoaPods](https://cocoapods.org), add this to your `Podfile`:\n\n```ruby\npod 'adzerk-ios-sdk', '~\u003e 2.3.2\n```\n\nAgain, if you want to be on the latest master branch:\n\n```ruby\nuse_frameworks!\n\npod 'adzerk-ios-sdk', github: 'adzerk/adzerk-ios-sdk', branch: 'master'\n```\n\nThen run `pod install` to download the code and integrate it into your project. You'll then open the pod-created workspace instead of your project to build.\n\n## Examples\n\n### API Credentials \u0026 Required IDs\n\n- Network ID: Log into [Adzerk UI](https://app.adzerk.com/) \u0026 use the \"circle-i\" help menu in upper right corner to find Network ID. Required for all SDK operations.\n- Site ID: Go to [Manage Sites page](https://app.adzerk.com/#!/sites/) to find site IDs. Required when fetching an ad decision.\n- Ad Type ID: Go to [Ad Sizes page](https://app.adzerk.com/#!/ad-sizes/) to find Ad Type IDs. Required when fetching an ad decision.\n- User Key: UserDB IDs are [specified or generated for each user](https://dev.adzerk.com/reference/userdb#passing-the-userkey).\n\n### Fetching an Ad Decision\n\n```swift\nimport AdzerkSDK\n\n// Demo network, site, \u0026 ad type IDs; find your own via the Adzerk UI!\nDecisionSDK.defaultNetworkId = 23\nDecisionSDK.defaultSiteId = 667480\n\nlet client = DecisionSDK()\n\nvar p = Placements.custom(divName: \"div0\", adTypes: [5])\n\nvar reqOpts = PlacementRequest\u003cStandardPlacement\u003e.Options()\nreqOpts.userKey = \"abc\"\nreqOpts.keywords = [\"keyword1\", \"keyword2\"]\n\nclient.request(placements: [p], options: reqOpts) {response in\n  dump(response)\n}\n\n// or if using Swift 5.5\n\nlet response = await client.request(placements: [p], options: reqOpts)\ndump(response)\n```\n\n### Distance Targeting\n\n```swift\nimport AdzerkSDK\n\n// Demo network, site, \u0026 ad type IDs; find your own via the Adzerk UI!\nDecisionSDK.defaultNetworkId = 23\nDecisionSDK.defaultSiteId = 667480\n\nlet client = DecisionSDK()\n\nvar p = Placements.custom(divName: \"div0\", adTypes: [5])\n\nvar reqOpts = PlacementRequest\u003cStandardPlacement\u003e.Options()\nreqOpts.userKey = \"abc\"\nreqOpts.additionalOptions = [\n  \"intendedLatitude\": .float(35.91868),\n  \"intendedLongitude\": .float(-78.96001),\n  \"radius\": .float(50) // in km\n]\n\nclient.request(placements: [p], options: reqOpts) { response in\n  dump(response)\n}\n```\n\n### Recording Impressions and Clicks\n\nUse with the fetch ad example above.\n\n#### Recording Impressions\n\n```swift\n// Impression pixel; fire when user sees the ad\nclient.request(placements: [p], options: reqOpts) {\n    switch $0 {\n    case .success(let response):\n        for decision in response.decisions {\n            print(decision.key)\n\n            for selection in decision.value {\n                dump(selection, maxDepth: 3)\n\n                print(\"\\nFiring impression pixel...\")\n                client.recordImpression(pixelURL: selection.impressionUrl!)\n            }\n        }\n\n    case .failure(let error):\n        print(error)\n    }\n}\n```\n\n#### Recording Clicks\n\n```swift\n// Click pixel; fire when user clicks on the ad\nclient.request(placements: [p], options: reqOpts) {\n    switch $0 {\n    case .success(let response):\n        for decision in response.decisions {\n            print(decision.key)\n\n            for selection in decision.value {\n                dump(selection, maxDepth: 3)\n\n                print(\"\\nFiring click pixel...\")\n                client.firePixel(url: selection.clickUrl!) { response in\n                    // status: HTTP status code\n                    print(response.statusCode)\n                    // location: click target URL\n                    print(response.location)\n                }\n\n                // or if using Swift 5.5\n\n                let response = await client.firePixel(url: selection.clickUrl!)\n                print(response.statusCode)\n                print(response.location)\n            }\n        }\n\n    case .failure(let error):\n        print(error)\n    }\n}\n```\n\nSince events have no revenue by default, overriding revenue on events adds new revenue. For example:\n\n```\nclient.firePixel(url: clickUrl, override: 0.5) { ...\n\n```\n\nSets a new value of $0.50 for the event.\n\n\n```\nclient.firePixel(url: clickUrl, additional: 1.0) { ...\n\n```\n\nSets a value of $1.00 for the event, or adds an additional $1.00 if the event has already had revenue set.\n\n\n```\nclient.firePixel(url: clickUrl, grossMerchandiseValue: 1.5) { ...\n\n```\n\nSets the gross merchandise value of $1.50 for the event.\n\n\n### UserDB: Reading User Record\n\n```swift\nimport AdzerkSDK\n\n// Demo network ID; find your own via the Adzerk UI!\nDecisionSDK.defaultNetworkId = 23\n\nlet keyStore = UserKeyStoreKeychain()\nkeyStore.save(userKey: \"abc\")\n\nlet client = DecisionSDK(keyStore: keyStore)\n\nclient.userDB().readUser() {response in\n  dump(response)\n}\n\n// or with Swift 5.5\n\nlet response = await client.userDB().readUser()\ndump(response)\n```\n\n### UserDB: Setting Custom Properties\n\n```swift\nimport AdzerkSDK\n\n// Demo network ID; find your own via the Adzerk UI!\nDecisionSDK.defaultNetworkId = 23\n\nlet keyStore = UserKeyStoreKeychain()\nkeyStore.save(userKey: \"abc\")\n\nlet client = DecisionSDK(keyStore: keyStore)\n\nlet props:[String: AnyCodable] = [\n    \"favoriteColor\":  .string(\"blue\"),\n    \"favoriteNumber\": .int(42),\n    \"favoriteFoods\":  .array([\n        .string(\"strawberries\"),\n        .string(\"chocolate\"),\n    ])\n]\n\nclient.userDB().postProperties(props) {response in\n  dump(response)\n}\n```\n\n## Usage\n\nAll API operations are done with an instance of [`DecisionSDK`](http://adzerk.github.io/adzerk-ios-sdk/Classes/DecisionSDK.html).\n\nFor most uses, a single Network ID and Site ID will be used for the entire application. If this is the case\nyou can configure it once in the `AppDelegate`:\n\n```swift\n@import AdzerkSDK\n\nfunc applicationDidFinishLaunching(...) {\n  DecisionSDK.defaultNetworkId = YOUR_NETWORK_ID\n  DecisionSDK.defaultSiteId = YOUR_SITE_ID\n}\n```\n\nFor requests that need a different Network ID or Site ID, you can specify this on the individual placement request.\n\nYou can also set a custom host if you need to, up front, like this:\n\n```swift\n  DecisionSDK.host = \"your custom host\"\n```\n\nNote that the host is just the domain part of the reuqests. Do not include a scheme like `https://` in your custom hosts.\n\n### Requesting Placements\n\nTo request a placement, you can build a type that conforms to `Placement` and specify the attributes you want to send.\n\nThere are two types of placements builtin:\n\n- `StandardPlacement`\n- `CustomPlacement`\n\n#### Standard Placement\n\nFor brevity, you can create placements using the `Placements` type:\n\n```swift\nlet placement = Placements.standard(...)\n```\n\n#### Custom Placement\n\nYou can use `CustomPlacement` if you need to send additional JSON data to the server:\n\n```swift\nlet placement = Placements.custom(...)\nplacement.additionalOptions = [\n  \"arbitraryKey\": .string(\"value\")\n]\n```\n\nThis feature is useful for beta features or features added to the API that haven't been officially supported via the SDK yet.\n\n#### Sending the Request\n\n```swift\n// Assumes that the default network ID and site ID are already set on DecisionSDK\n\nlet sdk = DecisionSDK()\nlet placement = Placements.standard(divName: \"div1\", adTypes: [1])\n\nsdk.request(placement: placement) { result in\n    // gives you a Swift Result of type Result\u003cPlacementResponse, AdzerkError\u003e\n}\n```\n\nLike individual placements, you can send `additionalOptions` at the request level:\n\n```swift\nlet sdk = DecisionSDK()\nlet placement = Placements.standard(divName: \"div1\", adTypes: [1])\nlet opts = PlacementRequest\u003cStandardPlacement\u003e.Options()\nopts.additionalOptions = [\n  \"arbitraryKey\": .string(\"value\")\n]\n\nsdk.request(placement: placement, options: opts) { result in\n    // gives you a Swift Result of type Result\u003cPlacementResponse, AdzerkError\u003e\n}\n```\n\n_Note: completion blocks are called on the main queue. If you want to be called back on a different queue, you can pass this queue to the DecisionSDK initializer._\n\n### Handling the Response\n\nA placement request will accept a completion block that is handed an instance of `Result\u003cPlacementResponse, AdzerkError\u003e`.\n\nHandle each case as appropriate for your application. In the case of `.success` you are given an `PlacementResponse`\nthat contains the decisions for each placement requested.\n\n## GDPR Consent\n\nConsent preferences can be specified when building a request. For example, to set GDPR consent for tracking in the European Union (this defaults to false):\n\n```swift\nvar options = PlacementRequest\u003cStandardPlacement\u003e.Options()\noptions.consent = Consent(gdpr: false)\n```\n\n## Logging\n\nBy default, warnings and errors will be directed to `os_log`. You can configure your desired log level:\n\n```swift\nDecisionSDK.logger.level = .debug\n```\n\n## App Transport Security\n\nAdzerk's API Server is compliant with App Transport Security.\n\n## Building / Running Tests\n\nYou can run tests using the command line:\n\n```\nswift test\n```\n\n## Generating Docs\n\nDocs are generated with [jazzy](https://github.com/Realm/jazzy) and are hosted on github pages. To install jazzy:\n\n```\n$ gem install jazzy\n```\n\n_If you're using system ruby, you'll probably need to prefix the above with `sudo`_.\n\nAll doc generation happens on a different detached branch. Make sure your working copy is clean, close Xcode, and switch to the `gh-pages` branch:\n\n```\n$ git checkout gh-pages\n```\n\nOnce there the content of the working directory becomes the static HTML site. Run the `generate_docs.sh` script to copy the latest version of the project from the `master` branch and run jazzy on it to generate the doc HTML:\n\n```\n$ ./generate_docs.sh\n```\n\nOnce done, commit changes and push to github:\n\n```\n$ git add .\n$ git commit -m \"Update docs\"\n$ git push\n```\n\nAfter a few seconds, your changes will be live on [https://adzerk.github.io/adzerk-ios-sdk](https://adzerk.github.io/adzerk-ios-sdk).\n\n# License\n\nThis SDK is released under the Apache 2.0 license. See [LICENSE](https://github.com/adzerk/adzerk-ios-sdk/tree/master/LICENSE) for more information.\n\n# Changelog\n\n- 2.3.1: Add support for group property to User schema\n\n- 2.3.0: Support null values in JSON response\n\n- 2.2.0: Support Swift 5.6\n\n- 2.1.1: Add support for gross merchandise value when firing pixel events\n\n- 2.1.0: Add general pixel firing support\n\n- 2.0.2: Support additionalOptions to the CustomPlacement and PlacementRequest\n\n- 2.0.1: Update visibility of some members to allow addiiton flexibility.\n\n- 2.0: Rewritten for Swift, Swift Package Manager. This is a breaking change, as many of the types have evolved to more closely match Swift style.\n\n- 1.2: Add support for configurable hostname overrides\n\n- 1.1: Read/update GDPR consent\n\n- 1.0.4: Objective-C compatibility fixes for placements and decisions.\n\n- 1.0.3: Turns off logging by default, adds control over how/when to log to the console.\n\n- 1.0.2: Can specify which queue the sdk calls you back on. Defaults to `DispatchQueue.main`\n\n- 1.0: Swift 3 support\n\n_Breaking change: The Objective-C status code was changed from `NSNumber *` to `NSInteger`, as Swift 3 no longer automatically maps `Int?` to `NSNumber *`._\n\n- 0.4: Initial release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadzerk%2Fadzerk-ios-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadzerk%2Fadzerk-ios-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadzerk%2Fadzerk-ios-sdk/lists"}