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 Secret
s, some Endpoint
s 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)
- Select
File
/Swift Packages
/Add Package Dependency…
from the menu. - Paste
https://github.com/sbertix/Swiftagram.git
. - Follow the steps.
- 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 supportsCombine
Publisher
s out of the box. -
SwiftagramCrypto, depending on SwCrypt and KeychainSwift, can be added to Swiftagram to extend its functionality, accessing the safer
KeychainStorage
and encryptedEndpoint
s (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 aWKWebView
for fetching cookies.
Caching
Caching of Secret
s 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.