Instagram Private API Swift

Overview

SwiftyInsta

Please notice SwiftyInsta may not be actively maintained at the moment of you reading this note.
Refer to #244 for more info.


CI Status Version License Platform

Instagram offers two kinds of APIs to developers. The Instagram API Platform (extremely limited in functionality and close to being discontinued), and the Instagram Graph API for Business and Creator accounts only.

However, Instagram apps rely on a third type of API, the so-called Private API or Unofficial API, and SwiftyInsta is an iOS, macOS, tvOS and watchOS client for them, written entirely in Swift. You can try and create a better Instagram experience for your users, or write bots for automating different tasks.

These Private API require no token or app registration but they're not authorized by Instagram for external use. Use this at your own risk.

Installation

Swift Package Manager (Xcode 11 and above)

  1. Select File/Swift Packages/Add Package Dependency… from the menu.
  2. Paste https://github.com/TheM4hd1/SwiftyInsta.git.
  3. Follow the steps.

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate SwiftyInsta into your Xcode project using CocoaPods, specify it in your Podfile:

use_frameworks!

target '<Your Target Name>' do
    pod 'SwiftyInsta', '~> 2.0'
end

Then, run the following command:

$ pod install

SwiftyInsta depends on CryptoSwift and keychain-swift.

Login

Credentials

// these need to be strong references.
self.credentials = Credentials(username: /* username */, password: /* password */, verifyBy: .text)
self.handler = APIHandler()
handler.authenticate(with: .user(credentials)) {
    switch $0 {
    case .success(let response, _):
        print("Login successful.")
        // persist cache safely in the keychain for logging in again in the future.
        guard let key = response.persist() else { return print("`Authentication.Response` could not be persisted.") }
        // store the `key` wherever you want, so you can access the `Authentication.Response` later.
        // `UserDefaults` is just an example.
        UserDefaults.standard.set(key, forKey: "current.account")
        UserDefaults.standard.synchronize()
    case .failure(let error):
        if error.requiresInstagramCode {
            /* update interface to ask for code */
        } else {
            /* notify the user */
        }
    }
}

Once the user has typed the two factor authentication code or challenge code, you simply do

self.credentials.code = /* the code */

And the completionHandler in the previous authenticate(with: completionHandler:) will automatically catch the response.

LoginWebViewController (>= iOS 12 only)

let login = LoginWebViewController { controller, result in
    controller.dismiss(animated: true, completion: nil)
    // deal with authentication response.
    guard let (response, _) = try? result.get() else { return print("Login failed.") }
    print("Login successful.")
    // persist cache safely in the keychain for logging in again in the future.
    guard let key = response.persist() else { return print("`Authentication.Response` could not be persisted.") }
    // store the `key` wherever you want, so you can access the `Authentication.Response` later.
    // `UserDefaults` is just an example.
    UserDefaults.standard.set(key, forKey: "current.account")
    UserDefaults.standard.synchronize()
}
if #available(iOS 13, *) {
    present(login, animated: true, completion: nil) // just swipe down to dismiss.
} else {
    present(UINavigationController(rootViewController: login),  // already adds a `Cancel` button to dismiss it.
            animated: true,
            completion: nil)
}

Or implement your own custom UIViewController using LoginWebView, and pass it to an APIHandler authenticate method using .webView(/* your login web view */).

Authentication.Response

If you've already persisted a user's Authentication.Response:

// recover the `key` returned by `Authentication.Response.persist()`.
// in our example, we stored it in `UserDefaults`.
guard let key = UserDefaults.standard.string(forKey: "current.account") else { return print("`key` not found.") }
// recover the safely persisted `Authentication.Response`.
guard let cache = Authentication.Response.persisted(with: key) else { return print("`Authentication.Response` not found.") }
// log in.
let handler = APIHandler()
handler.authenticate(with: .cache(cache)) { _ in
    /* do something here */
}

Usage

All endpoints are easily accessible from your APIHandler instance.

let handler: APIHandler = /* a valid, authenticated handler */
// for instance you can…
// …fetch your inbox.
handler.messages.inbox(with: .init(maxPagesToLoad: .max),
                       updateHandler: nil,
                       completionHandler: { _, _ in /* do something */ })
// …fetch all your followers.
handler.users.following(user: .me,
                        with: .init(maxPagesToLoad: .max),
                        updateHandler: nil,
                        completionHandler: { _, _ in /* do something */ })

Futhermore, 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.).

Contributions

Pull requests and issues are more than welcome.

Authors

We're actively looking for maintainers.
Refer to #244 for more info.

License

SwiftyInsta is licensed under the MIT license. See LICENSE for more info.

Comments
  • Adding Multiple Accounts

    Adding Multiple Accounts

    Ciao

    I am trying to add multiple account feature. What i am trying to do is basically: Save cookies with user defaults with the key userPk

    But the problem is, when i am trying to add 2nd user, it brings back first user's cookies (somehow and although i delete all cookies) it shows me first user's feed.... So i can't even login for the second user

    Any idea on how to fix this?

    enhancement 
    opened by akkayanill 33
  • Login failure using webview

    Login failure using webview

    I'm receiving the following error message on try? result.get() using instagramcontroller, any idea why @TheM4hd1 ?

    "https://i.instagram.com/api/v1/accounts/current_user/.\nInvalid response.\nProcessing handler returned `nil`.\n403"
    
    invalid 
    opened by anonrig 28
  • Instagram Ajax Login

    Instagram Ajax Login

    Did Instagram just nuke instagram.com/accounts/login/ajax, or is it just me?
    I can't seem to make it work. 😱

    Do you mind testing the basic auth process? Cause unfortunately an alternative one would require way too many dependencies in Swift (as it uses both hashes and RSA).

    @TheM4hd1 @bariscck


    Edit: not working in Swiftagram either… 😱 did they really just get rid of it?

    critical 
    opened by sbertix 27
  • Ask about credentials.code

    Ask about credentials.code

    Hello, Please, tell me. I have a problem.

    With request in func login, I get an SMS with the code, that I registered in credentials.code = "121332". I can’t send this code back. How to do it? What am I doing wrong?

    This is my code

    class ViewController: UIViewController {

    let handler = APIHandler()    
    override func viewDidLoad() {
        super.viewDidLoad()
        login()
    }
    
    func login() {
        var credentials = Credentials(username: "username", password: "password", verifyBy: .text)
        credentials.code = "121332"
        
        handler.authenticate(with: .user(credentials)) { [weak self] in
            switch $0 {
            case .success(let response, _):
                print("Login successful.")
                guard let key = response.persist() else { return print("`Authentication.Response` could not be persisted.") }
                UserDefaults.standard.set(key, forKey: "current.account")
                UserDefaults.standard.synchronize()
                
                self?.getCurrentUser()
            case .failure(let error):
                if error.requiresInstagramCode {
                } else {
                }
            }
        }
    }
    
    func getCurrentUser() {
        self.handler.users.user(.me) { ( result: Result<User?, Error>) in
            switch result {
            case .success(let user):
                let username = user?.name ?? "John Doe"
                print("success, username: \(username)")
            case .failure(let error):
                print("failure, error: \(error.localizedDescription)")
            }
        }
    }
    

    }

    bug help wanted 
    opened by rmelnik7777 19
  • Sentry Block on login?

    Sentry Block on login?

    {"message": "Sorry, there was a problem with your request.", "status": "fail", "error_type": "sentry_block"}
    

    [-] Login failed: unExpected("sentry_block")

    is there something im doing wrong thats causing the sentry block, is there something i can do to prevent the sentry block?

    let user = SessionStorage.create(username: "\(String(username!))", password: "\(String(password!))")
                let userAgent = CustomUserAgent(apiVersion: "89.0.0.0", osName: "iOS", osVersion: "12", osRelease: "1.4", dpi: "458", resolution: "2688x1242", company: "Apple", model: "iPhone10,3", modem: "intel", locale: "en_US", fbCode: "95414346")
                HttpSettings.shared.addValue(userAgent.toString(), forHTTPHeaderField: Headers.HeaderUserAgentKey)
                let urlSession = URLSession(configuration: .default)
                let handler = try! APIBuilder().createBuilder().setHttpHandler(urlSession: urlSession).setRequestDelay(delay: .default).setUser(user: user).build()
                var _error: Error?
                do {
                    try handler.login { (result, cache) in
                        if result.isSucceeded {
                            DispatchQueue.main.async {
                                self.statusLabel!.text = "logged in"
                                self.bubbleColor!.image = UIImage(named: "bubble_green")
                                self.statusText!.textColor = UIColor(red:0.22, green:0.64, blue:0.04, alpha:1.0)
                            }
                            print("[+]: logged in")
                        } else {
                            print("[-] Login failed: \(result.info.error)")
                            _error = result.info.error
                            DispatchQueue.main.async {
                                self.statusLabel!.text = "login failed"
                                self.errorLabel!.text = "\(_error!)"
                                self.bubbleColor!.image = UIImage(named: "bubble_red")
                                self.statusText!.textColor = UIColor(red:0.91, green:0.06, blue:0.06, alpha:1.0)
                            }
                        }
                    }
                }
    
    help wanted question 
    opened by reefer 18
  • WebLogin not working

    WebLogin not working

    After update the pod weblogin not compiled in ios 10 version. When I change to 11.0 version of ios it says:

    • 'loginDelegate' is deprecated: use InstagramLoginWebView properties instead.
    • 'InstagramLoginWebViewDelegate' is deprecated: use InstagramLoginWebViewProtocol closure properties instead.

    When I changed InstagramLoginWebViewDelegate to InstagramLoginWebViewProtocol:

    • 'InstagramLoginWebViewProtocol' requires that 'LoginViewController' inherit from 'UIView'

    My Codes:

    class LoginViewController: UIViewController {

    var loginWebView: InstagramLoginWebView! = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        loginWebView = InstagramLoginWebView(frame: self.view.frame)
        self.view.addSubview(loginWebView!)
        loginWebView?.loginDelegate = self **-- Cannot assign value of type 'LoginViewController' to type 'InstagramLoginWebViewDelegate?'**
        self.loginWebView?.loadInstagramLogin(isNeedPreloadForCookieSync: true) **--Argument passed to call that takes no arguments**
    }
    

    }

    extension LoginViewController : InstagramLoginWebViewProtocol { --'InstagramLoginWebViewProtocol' requires that 'LoginViewController' inherit from 'UIView'

    func userLoggedSuccessfully() {
        print("User Logged Successfully")
        
        DispatchQueue.main.async {
            self.loginWebView.removeFromSuperview()
        }
             
    }
    
    help wanted 
    opened by effecttwins 16
  • Friendship status is not working

    Friendship status is not working

    Today i realized that friendshipStatus is not working anymore with the Invalid response. 405 error code.

    Reason for that might be .get .post methods. Because there are 2 types of getFriendshipstatus code one using .get and other (which is commented not used at the moment) using .post.

    bug 
    opened by swifty-things 14
  • Login stopped working

    Login stopped working

    Authenticating with cache or via LoginWebViewController fails with error: "https://i.instagram.com/api/v1/accounts/current_user/.\nInvalid response.\nProcessing handler returned nil.\n405"

    bug 
    opened by biox86 12
  • Follow and Unfollow methods are not working.

    Follow and Unfollow methods are not working.

    Hi,

    I am using your library and I am developing an iOS app.

    I try to follow or unfollow users but not working this methods.

    Can you check these methods?

    bug 
    opened by ahmetkocu 11
  • user.avatar returns nil

    user.avatar returns nil

    (lldb) p user.rawResponse.hdProfilePicVersions.array
    ([SwiftyInsta.DynamicResponse]?) $R8 = 2 values {
      [0] = dictionary {
        dictionary = 3 key/value pairs {
          [0] = {
            key = "height"
            value = number {
              number = 0xf0c1170ab455ee27 Int64(320)
            }
          }
          [1] = {
            key = "url"
            value = string (string = "https://scontent-lht6-1.cdninstagram.com/v/t51.2885-19/s320x320/46361553_356999201721545_4488569793045069824_n.jpg?_nc_ht=scontent-lht6-1.cdninstagram.com&_nc_ohc=OTtfnwxlEUYAX-TfSkQ&oh=4351f903d25a25311190e5775c485d34&oe=5ED948C2")
          }
          [2] = {
            key = "width"
            value = number {
              number = 0xf0c1170ab455ee27 Int64(320)
            }
          }
        }
      }
      [1] = dictionary {
        dictionary = 3 key/value pairs {
          [0] = {
            key = "height"
            value = number {
              number = 0xf0c1170ab455d227 Int64(640)
            }
          }
          [1] = {
            key = "width"
            value = number {
              number = 0xf0c1170ab455d227 Int64(640)
            }
          }
          [2] = {
            key = "url"
            value = string (string = "https://scontent-lht6-1.cdninstagram.com/v/t51.2885-19/s640x640/46361553_356999201721545_4488569793045069824_n.jpg?_nc_ht=scontent-lht6-1.cdninstagram.com&_nc_ohc=OTtfnwxlEUYAX-TfSkQ&oh=a816bd28e587758d0662aa6a7e7f180a&oe=5EDA4A2F")
          }
        }
      }
    }
    
     p user.avatar
    (URL?) $R6 = nil
    
    opened by mycroftcanner 11
  • Invalid response when uploading picture

    Invalid response when uploading picture

    Originally posted by @trentona in https://github.com/TheM4hd1/SwiftyInsta/issues/105#issuecomment-535255876

    ———————————————— "Thank you, its now getting "failure(SwiftyInsta.GenericError.custom("Invalid response. 400"))". This is my viewController, could you please show me my errors in this one or if your have a working function for posting an image that you could just cut and paste to me that would help me tremendously, I have no idea where this is going wrong"

        import UIKit
        import SwiftyInsta
        class DeploymentViewController: UIViewController {
    
            let handler = APIHandler()
            @IBOutlet weak var sampleImage: UIImageView!
    
      
                override func viewDidLoad() {
                        super.viewDidLoad()
    
                }
        
           @IBAction func test(_ sender: Any) {
    
    
                guard let key = UserDefaults.standard.string(forKey: "current.account") else { return 
        print("`key` not found.") }
    
                guard let cache = Authentication.Response.persisted(with: key) else { return 
        print("`Authentication.Response` not found.") }
                    handler.authenticate(with: .cache(cache)) { _ in    }
            
                let img1: Upload.Picture = Upload.Picture(image: self.sampleImage.image!, caption: 
        "sampleText", size: CGSize(width: 1080,height: 1080) )
            
        
                    self.handler.media.upload(photo: img1, completionHandler: { (result) in
                
                
                  
                    print(result)
                })    }
        
    
        }
    
    help wanted 
    opened by sbertix 11
Releases(2.6.0)
Owner
Mahdi Makhdumi
Just because you fall once, doesn't mean you're fall at everything. Keep trying, hold on, and always trust yourself, because if you don't then who will??
Mahdi Makhdumi
Fetch Multiple Rest API using Swift 5.5 Async Await with Task, TaskGroup, Continuation API

Source code for Tutorial on experimenting with Swift Async Await to fetch multiple REST API endpoints and eliminate Pyramid of Doom callback hell to improve code readability and maintanability

Alfian Losari 14 Dec 7, 2022
Swift implementation of Github REST API v3

GitHubAPI Swift implementation of GitHub REST api v3. Library support Swift 4.2. Work is in progress. Currently supported: Issues API. Activity API(Fe

Serhii Londar 77 Jan 7, 2023
Google Directions API helper for iOS, written in Swift

PXGoogleDirections Google Directions API SDK for iOS, entirely written in Swift. ?? Features Supports all features from the Google Directions API as o

Romain L 268 Aug 18, 2022
Swift Reddit API Wrapper

reddift reddift is Swift Reddit API Wrapper framework, and includes a browser is developed using the framework. Supports OAuth2(is not supported on tv

sonson 236 Dec 28, 2022
A Swift client for the OpenAI API.

OpenAI A Swift client for the OpenAI API. Requirements Swift 5.3+ An OpenAI API Key Example Usage Completions import OpenAI

Mattt 161 Dec 26, 2022
Swift Bot with Vapor for Telegram Bot Api

Telegram Vapor Bot Please support Swift Telegram Vapor Bot Lib development by giving a ⭐️ Telegram Bot based on Swift Vapor. Swift Server Side Communi

OleG. 104 Jan 6, 2023
Swift library for the Twitter API v1 and v2

Swift library for the Twitter API v1 and v2

mironal 96 Dec 30, 2022
Backport of iOS 15 formatting api

This is a back-port of the .formatted API in Foundation that was introduced at WWDC '21 for iOS 15, macOS 12.0, tvOS 15.0, and watchOS 8.0.

Simon Salomons 9 Jul 22, 2022
Unofficial iOS/macOS SDK for the Notion API.

NotionClient: a Notion SDK for iOS & macOS Unofficial Notion API SDK for iOS & macOS. This is an alpha version and still work in progress. TODO Featur

David De Bels 15 Aug 4, 2022
👤 Framework to Generate Random Users - An Unofficial Swift SDK for randomuser.me

RandomUserSwift is an easy to use Swift framework that provides the ability to generate random users and their accompanying data for your Swift applic

Wilson Ding 95 Sep 9, 2022
Swifter - A Twitter framework for iOS & OS X written in Swift

Getting Started Installation If you're using Xcode 6 and above, Swifter can be installed by simply dragging the Swifter Xcode project into your own pr

Matt Donnelly 2.4k Dec 26, 2022
Swift client for Kubernetes

Table of contents Overview Compatibility Matrix Examples Usage Creating a client Configuring a client Client authentication Client DSL Advanced usage

Swiftkube 94 Dec 14, 2022
SDK for creating Telegram Bots in Swift.

Chat • Changelog • Prerequisites • Getting started • Creating a new bot • Generating Xcode project • API overview • Debugging notes • Examples • Docum

Rapier 349 Dec 20, 2022
Telegram Bot Framework written in Swift 5.1 with SwiftNIO network framework

Telegrammer is open-source framework for Telegram Bots developers. It was built on top of Apple/SwiftNIO

Pataridze Givi 279 Jan 4, 2023
Solana + RxSolana This is a open source library on pure swift for Solana protocol

The objective is to create a cross platform, fully functional, highly tested and less depencies as posible. The project is still at initial stage. Lots of changes chan happen to the exposed api.

Arturo Jamaica 138 Dec 15, 2022
QuoteKit is a Swift framework to use the free APIs provided by Quotable created by Luke Peavey.

QuoteKit The QuoteKit is a Swift framework to use the free APIs provided by Quotable created by Luke Peavey.

Rudrank Riyam 17 Jun 23, 2022
A modern Swift wrapper for Instagram Private API.

Swiftagram is a wrapper for Instagram Private API, written entirely in (modern) Swift. Instagram's official APIs, both the Instagram Basic Display API

Stefano Bertagno 217 Dec 27, 2022
RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).

BlueRSA Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux

Kitura 122 Dec 16, 2022
RSA public/private key encryption, private key signing and public key verification in Swift using the Swift Package Manager. Works on iOS, macOS, and Linux (work in progress).

BlueRSA Swift cross-platform RSA wrapper library for RSA encryption and signing. Works on supported Apple platforms (using Security framework). Linux

Kitura 122 Dec 16, 2022
Instagram clone, the main focus of the app is the seamless swipe between views that we see on instagram

InstaSwipe Instagram clone, the main focus of the app is the seamless swipe betw

Stavros Pachoundakis 1 Dec 15, 2022