MisskeyKit for iOS
MisskeyKit 是一个用 Swift 编写的 Misskey 框架。您可以直观地调用 Misskey API。 (日语请参考 此处)
依赖
- Starscream
- Swift 5
内容
安装
CocoaPods
您可以通过将MisskeyKit
添加到您的Podfile
中来使用CocoaPods进行安装。
pod 'MisskeyKit'
为了获取全部功能,确保导入MisskeyKit
import MisskeyKit
手动安装
- 下载并将
MisskeyKit
放入项目中。 - 运行
carthage update
。 - 恭喜您!
如何使用
单例模式
MisskeyKit采用单例模式,因为它需要保持账户信息,而不是直接由开发者来管理。
因此,您必须始终通过以下实例与MisskeyKit进行通信。
open class MisskeyKit {
static public let auth: Auth
static public var notes: Notes
static public var users: Users
static public var groups: Groups
static public var lists: Lists
static public var search: Search
static public var notifications: Notifications
static public var meta: Meta
如何更改Misskey实例
要更改Misskey实例,请使用MisskeyKit.changeInstance()
。
MisskeyKit.changeInstance(instance: "misskey.dev")
身份验证
身份验证有5个原生步骤。
- 访问开发者中心并获得
Secret Key
(也称为appSecret
)。 - 获取
会话令牌
。 - 用户通过safari进行身份验证。
- 获取
访问令牌
。 - 最后,获取
API密钥
!
另一方面,MisskeyKit非常简单。
您只需要设置并显示 MisskeyKit.auth.viewController
,它将会启动浏览器进行身份验证,代替您完成繁琐的过程。
此外,您可以选择是否使用回调模式或委托模式!
回调模式
MisskeyKit.auth.appSecret = "Enter your Secret Key"
let authVC = MisskeyKit.auth.viewController
authVC.resultApiKey() { apiKey in
guard let apiKey = apiKey else { return }
print(apiKey) // u can get uesr's apikey.
}
self.present(authVC, animated: true)
委托模式
class ViewController: UIViewController, AuthViewControllerDelegate {
func something() {
MisskeyKit.auth.appSecret = "Enter your Secret Key"
let authVC = MisskeyKit.auth.viewController
authVC.delegate = self
self.present(authVC, animated: true)
}
//....
func resultApiKey(_ apiKey: String?) { // Need: AuthViewControllerDelegate
guard let apiKey = apiKey else { return }
print(apiKey) // u can get uesr's apikey.
}
身份验证(高级)
您也可以按正确的顺序调用身份验证API。
获取会话令牌
MisskeyKit.auth.startSession(appSecret: "Enter your appSecret") { auth, error in
guard let auth = auth, let token = auth.token, error == nil else { /* Error */ return }
print(token) // u got a Session Token.
}
获取后,您需要让您的用户通过safari进行身份验证。
例如,
MisskeyKit.auth.startSession(appSecret: "Enter your appSecret") { auth, error in
guard let auth = auth, let token = auth.token, error == nil else { /* Error */ return }
print(token) // u got a Session Token.
guard let url = URL(string: token.url) else { /* Error */ return }
DispatchQueue.main.async {
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
}
获取访问令牌
MisskeyKit.auth.getAccessToken() { auth, error in
guard let auth = auth, error == nil else { return }
print(auth.me) // u got a Session Token.
}
获取API密钥
// If u get user's Access Token correctly, u can get Api key.
guard let apikey = MisskeyKit.auth.getAPIKey() else {
/* Error */
}
回收Api Key
如果想回收用户的api key,必须将其发送给MisskeyKit,所以使用MisskeyKit.auth.setAPIKey()
。
MisskeyKit.auth.setAPIKey("Enter saved api key!")
如何调用API
看看MisskeyKit的代码,看看如何描述。
哎呀,太麻烦了?嗯...好吧,我就给你举三个例子。
例如,如果你要发布一条笔记,检查以下代码。
(一旦获取或设置了用户的api key,就不再需要将Api key发送到每个方法中。)
// Type of the first parameter "posts" will change according to purpose of methods you use.
// In this method, type is NoteModel. You can see model class in "./MisskeyKit/APIs/Model".
MisskeyKit.notes.createNote(text: "Enter some text!") { posts, error in
guard let posts = posts, error == nil else { /* Error */ return }
// MisskeyKit.notes.createNote returns information of your post that you've just posted.
// The fact itself that you receive it means that your request was accepted successfully.
print(posts)
}
第二个示例:如果你想从用户的动态中获取一百条笔记,代码如下。
MisskeyKit.notes.getTimeline(limit: 100) { posts, error in
guard let posts = posts, error == nil else { /* Error */ return }
print(posts) // You can check 100 notes if your request was accepted successfully.
}
最后一个示例:MisskeyKit.drive.createFile
,这是一个用于“drive/create” api的方法。
当使用MisskeyKit.drive.createFile
时,你总是必须添加fileType。(fileType预期是MIME类型。)
MisskeyKit.drive.createFile(fileData: targetImage, fileType: "image/jpeg", name: UUID().uuidString + ".jpeg", isSensitive: false, force: false) { result, error in
guard let result = result, error == nil else { return }
print(result.id)
}
API方法对应表
Misskey API | MisskeyKit 方法 |
---|---|
users/show | Users.showUser |
i | Users.i |
i/favorites | Users.getAllFavorites |
i/page-likes | Users.getLikedPages |
i/pages | Users.getMyPages |
i/update | Users.updateMyAccount |
i/pin | Users.pin |
i/unpin | Users.unpin |
following/create | Users.follow |
following/delete | Users.unfollow |
users/followers | Users.getFollowers |
users/following | Users.getFollowing |
users/get-frequently-replied-users | Users.getFrequentlyRepliedUsers |
users/relation | Users.getUserRelationship |
blocking/create | Users.block |
blocking/delete | Users.unblock |
blocking/list | Users.getBlockingList |
users/report-abuse | Users.reportAsAbuse |
users/recommendation | Users.getUserRecommendation |
following/requests/accept | Users.acceptFollowRequest |
following/requests/cancel | Users.cancelFollowRequest |
following/requests/reject | Users.rejectFollowRequest |
notes | Notes.getAllNotes |
notes/show | Notes.showNote |
notes/conversation | Notes.getConversation, Notes.getChildren |
users/notes | Notes.getUserNotes |
notes/mentions | Notes.getMentionsForMe |
notes/timeline | Notes.getTimeline |
notes/global-timeline | Notes.getGlobalTimeline |
notes/hybrid-timeline | Notes.getHybridTimeline |
notes/local-timeline | Notes.getLocalTimeline |
notes/user-list-timeline | Notes.getUserListTimeline |
notes/featured | Notes.getFeatured |
notes/create | Notes.createNote, Notes.renote |
notes/delete | Notes.deletePost |
notes/favorites/create | Notes.createFavorite |
notes/favorites/delete | Notes.deleteFavorite |
notes/reactions | Notes.getReactions |
notes/reactions/create | Notes.createReaction |
notes/reactions/delete | Notes.deleteReaction |
notes/renotes | Notes.getRenotes |
notes/unrenote | Notes.unrenote |
notes/replies | Notes.getReplies |
notes/watching/create | Notes.watchNote |
notes/watching/delete | Notes.unWatchNote |
i/read-all-unread-notes | Notes.readAllUnreadNotes |
notes/polls/vote | Notes.vote |
auth/session/generate | Auth.startSession |
meta | Meta.get |
users/groups/invitations/accept | Groups.acceptInvitation |
users/groups/invitations/reject | Groups.rejectInvitation |
users/groups/invite | Groups.invite |
users/groups/pull | Groups.pullUser |
users/groups/transfer | Groups.transferUser |
mute/create | Mute.create |
mute/delete | Mute.delete |
mute/list | Mute.getList |
drive/files/attached-notes | Drive.getAttachedNotes |
drive/files/delete | Drive.deleteFile |
drive/files/update | Drive.updateFile |
drive/files/upload-from-url | Drive.uploadFileFromUrl |
drive/folders/delete | Drive.deleteFolder |
drive/folders/update | Drive.updateFolder |
users/lists/pull | Lists.pullUser |
users/lists/push | Lists.pushUser |
users/lists/create | Lists.create |
users/lists/delete | Lists.delete |
users/lists/show | Lists.show |
users/lists/list | Lists.getMyLists |
users/lists/update | Lists.update |
i/read-all-messaging-messages | Messaging.readAllMessaging |
messaging/history | Messaging.getHistory |
messaging/messages | Messaging.getMessageWithUser, Messaging.create |
messaging/messages/delete | Messaging.delete |
messaging/messages/read | Messaging.read |
users/search | Search.user |
notes/search | Search.notes |
notes/search-by-tag | Search.notesByTag |
i/notifications | Notificaitons.get |
notifications/mark-all-as-read | Notificaitons.markAllAsRead |
表情符号
Misskey 实例有自己的自定义表情符号,并允许用户在反应和帖子中使用它们。
然而,有时从 Misskey 服务器发送给我们的用户帖子(笔记)和反应数据中不包含用户使用的自定义表情符号信息。
此外,如果您想开发类似表情符号选择器这样的东西,您必须获取默认和自定义表情符号数据。
因此,MisskeyKit 提供了一些获取默认/自定义表情符号数据的方法。
MisskeyKit.Emojis.getDefault{ result in
guard let result = result else { /* Error */ return }
dump(result) // you can see information of default emojis
}
MisskeyKit.Emojis.getCustom{ result in
guard let result = result else { /* Error */ return }
dump(result) // you can see information of custom emojis
}
一旦从 Misskey 实例服务器获取到表情符号信息,MisskeyKit 就会保留这些数据,直到用户关闭您的应用程序。
因此,您无需多次与 Misskey 实例服务器通信,从而降低了开销。
流式 API
MisskeyKit 还提供了流式 API 以及 REST API 的包装器。
(流式 API 是一种订阅机制,将客户端绑定到服务器,以便您可以近乎实时地接收事件。)
流式API
不采用HTTP协议,而是使用WebSocket,因此您需要使用其他方法连接到服务器。
然而,通过MisskeyKit连接WebSocket非常简单!
MisskeyKit.Streaming.connect()
您只需使用MisskeyKit.Streaming.connect()
即可!
(MisskeyKit.Streaming
不提供单例实例,因此您必须自己生成实例。)
guard let apiKey = MisskeyKit.auth.getAPIKey() else { return }
let streaming = MisskeyKit.Streaming() // u have to generate instance yourself.
streaming.connect(apiKey: apiKey, channels: [.main, .homeTimeline]) { response, channel, type, error in
// Do something ...
//apiKey: Your Api Key.
//channels: [SentStreamModel.Channel] Type / channels which you wanna connect to.
//This closure captures and sends you events through channels which you subscribed.
//response: Any? Type / events itself. You have to cast it according to type(third params of callback).
//channel: SentStreamModel.Channel? Type / shows which channel sent events.
//type: String? Type / shows what kind of events was sent. You'll use it to cast response.
//error: Error? Type / If something wrong happens, error is sent
}
MisskeyKit.Streaming.captureNote()
即使您使用MisskeyKit.Streaming.connect()
并监听事件,也有一些您无法接收的注意事项。
对于这些笔记,您必须调用提供捕获功能的API(点击这里获取详细信息。)
如果您想捕获一些笔记,请使用MisskeyKit.Streaming.captureNote()
do {
try streaming.captureNote(noteId: "Enter note Id.")
}
catch {
/* Error */
}
一旦捕获到一个笔记,与该笔记相关的每个事件都将发送到MisskeyKit.streaming.connect()
的回调方法。
MisskeyKit.Streaming.isConnected
这个变量使我们能够检查流是否已连接。
guard streaming.isConnected else { return }
// Good.
MisskeyKit.Streaming.stopListening()
如果您想断开特定的频道,请使用MisskeyKit.Streaming.stopListening()
。
streaming.stopListening(channnel: SentStreamModel.Channel)
streaming.stopListening(channnels: [SentStreamModel.Channel])
streaming.stopListening(noteId: String)
streaming.stopListening(noteIds: [String])
MisskeyKitError
MisskeyKit有自己的错误枚举,这样我们就可以更灵活地处理一些错误。
public enum MisskeyKitError: Error {
//These Error are corresponded to error codes sent by Misskey server.
//400
case ClientError
//401
case AuthenticationError
//403
case ForbiddonError
//418
case ImAI
//429
case TooManyError
//500
case InternalServerError
//These Error are related to internal error.
case CannotConnectStream
case NoStreamConnection
case FailedToDecodeJson
case FailedToCommunicateWithServer
case UnknownTypeResponse
case ResponseIsNull
}
贡献力量
我们非常欢迎您对 MisskeyKit 的贡献,更多详情请查看 LICENSE
文件。
其他
Yuiga Wada - 网站 Twitter - @YuigaWada
在MIT许可证下分发。更多信息请查看 LICENSE
。