{"id":13465340,"url":"https://github.com/TheM4hd1/SwiftyInsta","last_synced_at":"2025-03-25T16:31:36.399Z","repository":{"id":34295648,"uuid":"154579815","full_name":"TheM4hd1/SwiftyInsta","owner":"TheM4hd1","description":"Instagram Private API Swift","archived":false,"fork":false,"pushed_at":"2022-03-09T17:24:41.000Z","size":1884,"stargazers_count":224,"open_issues_count":0,"forks_count":56,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-10-20T16:03:47.268Z","etag":null,"topics":["api","client","instagram","instagram-api","instagram-like","ios-swift","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/TheM4hd1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"them4hd1","custom":["https://www.paypal.me/them4hd1"]}},"created_at":"2018-10-24T22:59:37.000Z","updated_at":"2024-09-22T12:42:45.000Z","dependencies_parsed_at":"2022-08-08T00:15:37.907Z","dependency_job_id":null,"html_url":"https://github.com/TheM4hd1/SwiftyInsta","commit_stats":null,"previous_names":[],"tags_count":68,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheM4hd1%2FSwiftyInsta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheM4hd1%2FSwiftyInsta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheM4hd1%2FSwiftyInsta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheM4hd1%2FSwiftyInsta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheM4hd1","download_url":"https://codeload.github.com/TheM4hd1/SwiftyInsta/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222088538,"owners_count":16928976,"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":["api","client","instagram","instagram-api","instagram-like","ios-swift","swift"],"created_at":"2024-07-31T15:00:27.839Z","updated_at":"2024-10-29T17:30:43.730Z","avatar_url":"https://github.com/TheM4hd1.png","language":"Swift","funding_links":["https://github.com/sponsors/them4hd1","https://www.paypal.me/them4hd1"],"categories":["Libs","API [🔝](#readme)","Networking"],"sub_categories":["API"],"readme":"# SwiftyInsta (legacy)\n\n\u003e Please notice **SwiftyInsta** is no longer actively maintained.\u003cbr /\u003e\n\u003e Refer to [#244](https://github.com/TheM4hd1/SwiftyInsta/issues/244) for more info.\u003cbr /\u003e\n\u003e Check out [**Swiftagram**](https://github.com/sbertix/Swiftagram) if you're looking for up-to-date alternatives.\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n[![CI Status](https://img.shields.io/travis/TheM4hd1/SwiftyInsta/master.svg?style=flat)](https://travis-ci.org/TheM4hd1/SwiftyInsta)\n[![Version](https://img.shields.io/cocoapods/v/SwiftyInsta.svg?style=flat)](https://cocoapods.org/pods/SwiftyInsta)\n[![License](https://img.shields.io/cocoapods/l/SwiftyInsta.svg?style=flat)](https://github.com/TheM4hd1/SwiftyInsta/LICENSE.md)\n[![Platform](https://img.shields.io/cocoapods/p/SwiftyInsta.svg?style=flat)](https://cocoapods.org/pods/SwiftyInsta)\n\u003cimg src=\"https://img.shields.io/badge/supports-CocoaPods%2C%20Swift%20Package%20Manager-ff69b4.svg\"\u003e\n\n**Instagram** offers two kinds of APIs to developers. The [Instagram API Platform](https://www.instagram.com/developer/) (extremely limited in functionality and close to being discontinued), and the [Instagram Graph API](https://developers.facebook.com/docs/instagram-api) for _Business_ and _Creator_ accounts only.\n\nHowever, **Instagram** apps rely on a third type of _API_, the so-called **Private API** or _Unofficial API_, and [SwiftyInsta](https://github.com/TheM4hd1/SwiftyInsta) is an **iOS, macOS, tvOS and watchOS client** for them, written entirely in **Swift**.\nYou can try and create a better Instagram experience for your users, or write bots for automating different tasks.\n\nThese _Private API_ require no _token_ or _app registration_ but they're not _authorized_ by Instagram for external use.\nUse this at your own risk.\n\n## Installation\n### Swift Package Manager (Xcode 11 and above)\n1. Select `File`/`Swift Packages`/`Add Package Dependency…` from the menu.\n1. Paste `https://github.com/TheM4hd1/SwiftyInsta.git`.\n1. Follow the steps.\n\n### CocoaPods\n[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:\n```terminal\n$ gem install cocoapods\n```\nTo integrate **SwiftyInsta** into your Xcode project using CocoaPods, specify it in your `Podfile`:\n```text\nuse_frameworks!\n\ntarget '\u003cYour Target Name\u003e' do\n    pod 'SwiftyInsta', '~\u003e 2.0'\nend\n```\nThen, run the following command:\n```terminal\n$ pod install\n````\n\n**SwiftyInsta** depends on [CryptoSwift](https://github.com/krzyzanowskim/CryptoSwift)\u003c!--[GzipSwift](https://github.com/1024jp/GzipSwift),--\u003e and [keychain-swift](https://github.com/evgenyneu/keychain-swift).\n\n\u003c!--\n### Manually\nTo use this library in your project manually you may:\n    - Add compiled framework from ```General \u003e Linked frameworks and libraries```\n    - Clone the project, right click on your root project(not SwiftyInsta) and select ```Add files...```, then select the ```SwiftyInsta.xcodeproj```. after that go to your ```project\u003eembeded libraries``` and select ```SwiftyInsta.framework```, build the project and import ```SwiftyInsta```\n--\u003e\n\n## Login\n### `Credentials`\n```swift\n// these need to be strong references.\nself.credentials = Credentials(username: /* username */, password: /* password */, verifyBy: .text)\nself.handler = APIHandler()\nhandler.authenticate(with: .user(credentials)) {\n    switch $0 {\n    case .success(let response, _):\n        print(\"Login successful.\")\n        // persist cache safely in the keychain for logging in again in the future.\n        guard let key = response.persist() else { return print(\"`Authentication.Response` could not be persisted.\") }\n        // store the `key` wherever you want, so you can access the `Authentication.Response` later.\n        // `UserDefaults` is just an example.\n        UserDefaults.standard.set(key, forKey: \"current.account\")\n        UserDefaults.standard.synchronize()\n    case .failure(let error):\n        if error.requiresInstagramCode {\n            /* update interface to ask for code */\n        } else {\n            /* notify the user */\n        }\n    }\n}\n```\n\nOnce the user has typed the two factor authentication code or challenge code, you simply do\n```swift\nself.credentials.code = /* the code */\n```\nAnd the `completionHandler` in the previous `authenticate(with: completionHandler:)` will automatically catch the response.\n\n\n### `LoginWebViewController`\n```swift\nlet login = LoginWebViewController { controller, result in\n    controller.dismiss(animated: true, completion: nil)\n    // deal with authentication response.\n    guard let (response, _) = try? result.get() else { return print(\"Login failed.\") }\n    print(\"Login successful.\")\n    // persist cache safely in the keychain for logging in again in the future.\n    guard let key = response.persist() else { return print(\"`Authentication.Response` could not be persisted.\") }\n    // store the `key` wherever you want, so you can access the `Authentication.Response` later.\n    // `UserDefaults` is just an example.\n    UserDefaults.standard.set(key, forKey: \"current.account\")\n    UserDefaults.standard.synchronize()\n}\nif #available(iOS 13, *) {\n    present(login, animated: true, completion: nil) // just swipe down to dismiss.\n} else {\n    present(UINavigationController(rootViewController: login),  // already adds a `Cancel` button to dismiss it.\n            animated: true,\n            completion: nil)\n}\n```\nOr implement your own custom `UIViewController` using `LoginWebView`, and pass it to an `APIHandler` `authenticate` method using `.webView(/* your login web view */)`.\n\n### `Authentication.Response`\nIf you've already persisted a user's `Authentication.Response`:\n\n```swift\n// recover the `key` returned by `Authentication.Response.persist()`.\n// in our example, we stored it in `UserDefaults`.\nguard let key = UserDefaults.standard.string(forKey: \"current.account\") else { return print(\"`key` not found.\") }\n// recover the safely persisted `Authentication.Response`.\nguard let cache = Authentication.Response.persisted(with: key) else { return print(\"`Authentication.Response` not found.\") }\n// log in.\nlet handler = APIHandler()\nhandler.authenticate(with: .cache(cache)) { _ in\n    /* do something here */\n}\n```\n\n## Usage\nAll endpoints are easily accessible from your `APIHandler` instance.\n\n```swift\nlet handler: APIHandler = /* a valid, authenticated handler */\n// for instance you can…\n// …fetch your inbox.\nhandler.messages.inbox(with: .init(maxPagesToLoad: .max),\n                       updateHandler: nil,\n                       completionHandler: { _, _ in /* do something */ })\n// …fetch all your followers.\nhandler.users.following(user: .me,\n                        with: .init(maxPagesToLoad: .max),\n                        updateHandler: nil,\n                        completionHandler: { _, _ in /* do something */ })\n```\n\nFuthermore, responses now display every single value contained in the `JSON` file returned by the **API**: just access any `ParsedResponse` `rawResponse` and start browsing, or stick with the suggested accessories (e.g. `User`'s `username`, `name`, etc. and `Media`'s `aspectRatio`, `takenAt`, `content`, etc.).\n\n## Contributions\n\n_Pull requests_ and _issues_ are more than welcome.\n\n\u003c!-- Remove sourcer.io because of it being discontinued. --\u003e\n### Authors\n- [Mahdi Makhdumi (**@TheM4hd1**)](https://github.com/them4hd1), `1.*` _maintainer_\n- [Stefano Bertagno (**@sbertix**)](https://github.com/sbertix), `2.*` _maintainer_\n\n\u003e We're actively looking for maintainers.\u003cbr /\u003e\n\u003e Refer to [#244](https://github.com/TheM4hd1/SwiftyInsta/issues/244) for more info.\n\n## License\n\n**SwiftyInsta** is licensed under the MIT license. See [LICENSE](https://github.com/TheM4hd1/SwiftyInsta/blob/master/LICENSE) for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTheM4hd1%2FSwiftyInsta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTheM4hd1%2FSwiftyInsta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTheM4hd1%2FSwiftyInsta/lists"}