Git Product home page Git Product logo

mastodonkit's Introduction

MastodonKit

Build Status Code Coverage SwiftPM Compatible SwiftPM Version

MastodonKit is a Swift Framework built using Swift Package Manager that wraps the Mastodon API. Its goal is to cover all the entities and endpoints from Mastodon's API.

By the way, if you want to get in touch with me, toot me.

Table of content

Building it from source

MastodonKit uses the Swift Package Manager and can be built and tested using the following commands:

$ git clone https://github.com/MastodonKit/MastodonKit.git
$ cd MastodonKit
$ swift build
$ swift test

If you prefer, Swift Package Manager can create an Xcode Project:

$ swift package generate-xcodeproj
$ open MastodonKit.xcodeproj

Initializing the client

Assuming you already have an access token for a user on the given Mastodon instance:

let client = Client(
    baseURL: "https://mastodon.technology",
    accessToken: "user access token (after OAuth login)"
)

Shall you need to get an access token, you must first register the application against the given Mastodon instance. Registering an application returns the Client ID and Client Secret needed to perform the OAuth call. Remember to store the Client ID and Client Secret locally in your application for future OAuth logins:

let client = Client(baseURL: "https://mastodon.technology")

let resource = Clients.register(
    clientName: "MastodonKit Test Client",
    scopes: [.read, .write, .follow],
    website: "https://github.com/MastodonKit/MastodonKit"
)

client.run(resource) { application, error in
    if let application = application {
        print("id: \(application.id)")
        print("redirect uri: \(application.redirectURI)")
        print("client id: \(application.clientID)")
        print("client secret: \(application.clientSecret)")
    }
}

After retrieving the access token (via standard OAuth 2 authorization flow), update the MastodonKit client with the returned accessToken:

client.accessToken = "user access token (after OAuth login)"

Side note: Mastodon's API and MastodonKit offer a way to silently log a user in, but the method is discouraged. The API documentation recommends using the standard OAuth 2 authorization flow instead.

"Please note that the password-based approach is not recommended especially if you're dealing with other user's accounts and not just your own. Usually you would use the authorization grant approach where you redirect the user to a web page on the original site where they can login and authorize the application and are then redirected back to your application with an access code." - Mastodon's API Documentation

But in case you want to test it with your own account, here is how:

let loginResource = Login.silent(
    clientID: "very long client id",
    clientSecret: "very long client secret",
    scopes: [.read, .write],
    username: "foo",
    password: "bar"
)

client.run(loginResource) { loginSettings, error in
    if let loginSettings = loginSettings {
        print("access token: \(loginSettings.accessToken)")
    }
}

Bear in mind the method above should never be used when deadling with other user's accounts.

Making requests

To make requests, create a resource and run it using the client. Two examples:

Getting the home timeline:

let resource = Timelines.home()

client.run(resource) { statuses, error in
    // do something with 'statuses'
}

Posting a new status:

let resource = Statuses.create("Mastodon's API is awesome!")

client.run(resource) { status, error in
    // do something with 'status'
}

Ranges and Limits

Some resources take an optional ResourceRange parameter. This parameter should be used to specify the range of IDs to get and the number of entities to fetch. The possible options are:

  • .since(id: Int, limit: Int?): Gets a list with IDs greater than this value.
    • Note: Passing nil as limit asks Mastodon to return the default number of entities for that endpoint.
  • .max(id: Int, limit: Int?): Gets a list with IDs less than or equal this value.
    • Note: Passing nil as limit asks Mastodon to return the default number of entities for that endpoint.
  • .limit(Int): Sets the maximum number of entities to get.
  • .default: Applies the default values.

Omitting the range paramater on the method call has the same effect of passing .default.

Examples:

// Since + limit
let resource = Timelines.home(range: .since(id: 42, limit: 30))

// Limit
let resource = Timelines.home(range: .limit(30))

// Max + default limit
let resource = Timelines.home(range: .max(id: 42, limit: nil))

// Default range and limit
let resource = Timelines.home()
let resource = Timelines.home(range: .default)

Uploading media attachments

To upload images to Mastodon, create a media attachment containing the file data (Data) and then pass the media attachment as argument to the Media.upload(media:) method. Supported media attachments types are .jpeg, .png, and .gif. Examples:

Uploading the JPEG representation of an UIImage:

let image = UIImage(named: "mastodon_logo")
let imageData = UIImageJPEGRepresentation(image, 0.82)

let resource = Media.upload(media: .jpeg(imageData))

client.run(resource) { attachment, error in
    // do something with 'attachment'
}

Uploading a GIF image from the main bundle:

let imagePath = Bundle.main.path(forResource: "funny_meme", ofType: ".gif")
let imageData = try? Data(contentsOf: URL(fileURLWithPath: imagePath!))

let imageUpload = Media.upload(media: .gif(imageData))

client.run(resource) { attachment, error in
    // do something with 'attachment'
}

Use the URL and id from attachment when creating a status.

List of resources

Below the qualified symbol name for the resources implemented by MastodonKit. All the methods are documented and their descriptions are available via option+click on Xcode.

Accounts

  • Accounts.account(id:) - fetches an account.
  • Accounts.currentUser() - gets the current user.
  • Accounts.updateCurrentUser(displayName:note:avatar:header:) - updates the current user.
  • Accounts.followers(id:range:) - gets an account's followers.
  • Accounts.following(id:range:) - gets who account is following.
  • Accounts.statuses(id:mediaOnly:excludeReplies:range:) - gets an account's statuses.
  • Accounts.follow(id:) - follows an account.
  • Accounts.unfollow(id:) - unfollow an account.
  • Accounts.block(id:) - blocks an account.
  • Accounts.unblock(id:) - unblocks an account.
  • Accounts.mute(id:) - mutes an account.
  • Accounts.unmute(id:) - unmutes an account.
  • Accounts.relationships(ids:) - gets an account's relationships.
  • Accounts.search(query:limit:) - searches for accounts.

Blocks

  • Blocks.all(range:) - fetches a user's blocks.

Clients

  • Clients.register(clientName:redirectURI:scopes:website:) - registers an application.

Favourites

  • Favourites.all(range:) - fetches a user's favourites.

Follow requests

  • FollowRequests.all(range:) - fetches a list of follow requests.
  • FollowRequests.authorize(id:) - authorizes a follow request.
  • FollowRequests.reject(id:) - rejects a follow request.

Instances

  • Instances.current() - gets instance information.

Login

  • Login.silent(clientID:clientSecret:scope:username:password:) - performs a silent login.

Media

  • Media.upload(media:) - uploads a media attachment.

Mutes

  • Mutes.all(range:) - fetches a user's mute:

Notifications

  • Notifications.all(range:) - fetches a user's notifications.
  • Notifications.notification(id:) - gets a single notification.
  • Notifications.dismissAll() - deletes all notifications for the authenticated user.
  • Notifications.dismiss(id:) - deletes a single notification for the authenticated user.

Reports

  • Reports.all() - fetches a user's reports.
  • Reports.report(accountID:statusIDs:reason:) - reports a user.

Search

  • Search.search(query:resolve:) - searches for content.

Statuses

  • Statuses.status(id:) - fetches a status.
  • Statuses.context(id:) - gets a status context.
  • Statuses.card(id:) - gets a card associated with a status.
  • Statuses.rebloggedBy(id:range:) - gets who reblogged a status.
  • Statuses.favouritedBy(id:range:) - gets who favourited a status.
  • Statuses.create(status:replyToID:mediaIDs:sensitive:spoilerText:visibility:) - posts a new status.
  • Statuses.delete(id:) - deletes a status.
  • Statuses.reblog(id:) - reblogs a status.
  • Statuses.unreblog(id:) - unreblogs a status.
  • Statuses.favourite(id:) - favourites a status.
  • Statuses.unfavourite(id:) - unfavourites a status.

Timelines

  • Timelines.home(range:) - retrieves the home timeline.
  • Timelines.public(local:range:) - retrieves the public timeline.
  • Timelines.tag(_:local:range:) - retrieves a tag timeline.

Contributors

Special thanks to:

License

Copyright (c) 2017 Ornithologist Coder and MastodonKit Contributors. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

mastodonkit's People

Contributors

ornithocoder avatar paulyhedral avatar vhbit avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.