A modern Swift wrapper for Instagram Private API

Swiftagram

Swiftagram is a client for Instagram written entirely in Swift.

How does it work?

Swiftagram relies on Instagram unofficial private APIs, used internally in the Android and iOS apps.

This is because Instagram's official APIs, both the Instagram Basic Display API and the Instagram Graph API, are either lacking support for even the most mundane of features or limited to a small audience (e.g. Professional, i.e. Creator and Influencer, accounts).

Do I need an API token?

Swiftagram requires no token or registration.
Unofficial APIs, though, are not authorized by Instagram for external use: use them at your own risk.

Where can I use this?

Swiftagram supports iOS, macOS, watchOS, tvOS and Linux.

What's SwiftagramCrypto?

Apps using encryption require specific disclosure before submission to the App Store.
Although Swiftagram cannot be considered App Store safe, we still think it's wise to separate everything requiring cryptography into their own target library, named SwiftagramCrypto.
Other than KeychainStorage, the prefered way to store Secrets, some Endpoints are SwiftagramCrypto only.

SwiftagramCrypto-specific endpoints

  • Endoint.Feed
    • .stories(by:)
  • Endpoint.Friendship
    • .follow(_:)
    • .unfollow(_:)
    • .remove(follower:)
    • .acceptRequest(from:)
    • .rejectRequest(from:)
    • .block(_:)
    • .unblock(_:)
  • Endpoint.Media.Posts
    • .like(_:)
    • .unlike(_:)
    • .archive(_:)
    • .unarchive(_:)
    • .comment(_:, on:, replyingTo:)
    • .delete(comments:, on:)
    • .delete(matching:)
    • .upload(image:, captioned:, tagging:, at:)
    • .upload(image:, size:, captioned:, tagging:, at:)
  • Endpoint.Media.Stories
    • .by(_:)

Status


You can find all changelogs on our Telegram channel.
Don't forget to subscribe to get all news and updates as soon as they're out.

What's next?

Check out our milestones, issues and the "WIP" dashboard.

Pull requests are more than welcome.
Just remember to refer to our guidelines and Code of Conduct, when you contribute.

Installation

Swift Package Manager (Xcode 11 and above)

  1. Select File/Swift Packages/Add Package Dependency… from the menu.
  2. Paste https://github.com/sbertix/Swiftagram.git.
  3. Follow the steps.
  4. Add SwiftagramCrypto together with Swiftagram for the full experience.

Why not CocoaPods, or Carthage, or ~blank~?

Supporting multiple dependency managers makes maintaining a library exponentially more complicated and time consuming.
Furthermore, with the integration of the Swift Package Manager in Xcode 11 and greater, we expect the need for alternative solutions to fade quickly.

Targets

  • Swiftagram depends on ComposableRequest, an HTTP client originally integrated in Swiftagram., and it's the core library.
    It supports Combine Publishers out of the box.

  • SwiftagramCrypto, depending on SwCrypt and KeychainSwift, can be added to Swiftagram to extend its functionality, accessing the safer KeychainStorage and encrypted Endpoints (e.g. Endpoint.Friendship.follow, Endpoint.Friendship.unfollow).

Usage

Check out our Examples or visit the (auto-generated) Documentation to learn about use cases.

Authentication

Authentication is provided through conformance to the Authenticator protocol, which, on success, returns a Secret containing all the cookies needed to sign an Endpoint's request.

The library comes with two concrete implementations.

  • BasicAuthenticator is code based and only requires username and password, while supporting two factor authentication (requires SwiftagramCrypto).
  • WebViewAuthenticator, available for iOS 11+ and macOS 10.13+, relying on a WKWebView for fetching cookies.

Caching

Caching of Secrets is provided through conformance to the Storage protocol.

The library comes with several concrete implementations.

  • TransientStorage should be used when no caching is necessary.
  • UserDefaultsStorage allows for faster, out-of-the-box, testing, although it's not recommended for production as private cookies are not encoded.
  • KeychainStorage, part of SwiftagramCrypto, (preferred) stores them safely in the user's keychain.

Request

How can I bypass Instagram "spam" filter, and make them believe I'm not actually a bot?

Just set the default waiting time in the Requester to something greater than 0.

import ComposableRequest
import Swiftagram
import SwiftagramCrypto

// Somewhere in your code, for instance in your `AppDelegate`, set a new `default` `Requester`.
// `O.5` to `1.5` seconds is a long enough time, usually.
// `Requester.instagram` deals about it for you.
Requester.default = .instagram

Or just create a custom Requester and pass it to every single request you make.

What if I wanna know the basic info about a profile?

All you need is the user identifier and a valid Secret.

let identifier: String = /* the profile identifier */
let secret: Secret = /* the authentication response */

// Perform the request.
Endpoint.User.summary(for: identifier)
    .unlocking(with: secret)
    .task {
        // Do something here.
    })
    .resume() // Strongly referenced by default, no need to worry about it.

What about cancelling an ongoing request?

Easy!

let secret: Secret = /* the authentication response */

// Perform the request.
let task = Endpoint.Friendship.following(secret.id)
    .unlocking(with: secret)
    .task(maxLength: 10,
          onComplete: { _ in },
          onChange: { _ in  
            // Do something here.
    })
    .resume() // Exhaust 10 pages of followers.

// Cancel it.
task?.cancel()

What about loading the next page?

Just resume it once more.
If it's still fetching, nothing's gonna happen. But if it's not and there are still more pages to be fetched, a new one will be requested.

GitHub