Easy and powerful way to interact with VK API for iOS and macOS.
๐ It's not ios-vk-sdk ๐
๐ One library for iOS and mac OS ๐
๐ค Fully written in Swift and doesn't contain any Objective-C code ๐ค
๐ฎ Very simple interface, made with care about those who will use it ๐ฎ
โ Fully strong typed that you can not shoot yourself in the leg โ
๐ High code quality with lot of unit tests, linter integration and CI ๐
๐ Frequent updates and bug fixes ๐
๐ LongPoll support ๐
- Requirements
- Integration
- Getting started
- Interaction with VK API
- Configuring
- Upload files
- Interaction with LongPoll
- Share dialog
- FAQ
- License
- Swift 4.0 +
- iOS 8.0 +
- macOS 10.10 +
- Xcode 9.0 +
Carthage (recommended)
github "SwiftyVK/SwiftyVK"
use_frameworks!
target '$MySuperApp$' do
pod 'SwiftyVK'
end
- Just drag SwiftyVK.framework or include the whole SwiftyVK.xcodeproj into project
- Link SwiftyVK.framework with application in Your target preferences -> General -> Embedded binaries
To start using SwiftyVK
you should implement SwiftyVKDelegate
protocol in your custom VKDelegate
class.
It is used to notify your app about important SwiftyVK lifecycle events.
For example:
import SwiftyVK
class VKDelegateExample: SwiftyVKDelegate {
func vkNeedsScopes(for sessionId: String) -> Scopes {
// Called when SwiftyVK attempts to get access to user account
// Should return a set of permission scopes
}
func vkNeedToPresent(viewController: VKViewController) {
// Called when SwiftyVK wants to present UI (e.g. webView or captcha)
// Should display given view controller from current top view controller
}
func vkTokenCreated(for sessionId: String, info: [String : String]) {
// Called when user grants access and SwiftyVK gets new session token
// Can be used to run SwiftyVK requests and save session data
}
func vkTokenUpdated(for sessionId: String, info: [String : String]) {
// Called when existing session token has expired and successfully refreshed
// You don't need to do anything special here
}
func vkTokenRemoved(for sessionId: String) {
// Called when user was logged out
// Use this method to cancel all SwiftyVK requests and remove session data
}
}
See full implementation in Example project
- Create new standalone application
- Save
application ID
from Preferences -> Application ID - Set up SwiftyVK with
application ID
andVKDelegate
obtained in the previous steps:
VK.setUp(appId: String, delegate: SwiftyVKDelegate)
in order to free up resources that holds SwiftyVK use:
VK.release()
note you must setup it again for further using
SwiftyVK provides several ways to authorize user. Choose the one that's more suitable for you.
This is a standard authorization method which shows web view with oAuth dialog. Suitable for most cases.
VK.sessions.default.logIn(
onSuccess: { _ in
// Start working with SwiftyVK session here
},
onError: { _ in
// Handle an error if something went wrong
}
)
If a user has the official VK app installed on their device, SwiftyVK can be authorized using it. To do that:
-
In Xcode -> Target -> Info -> URL Types
- Add new URL Type like
vk$YOUR_APP_ID$
(e.g. vk1234567890) - Add app schemas to Info.plist file:
- Add new URL Type like
<key>LSApplicationQueriesSchemes</key>
<array>
<string>vkauthorize</string>
<string>vk$YOUR_APP_ID$</string>
</array>
-
Copy
Application Bundle
from Xcode -> $App Target$ -> General -> Bundle Identifier (e.g. com.developer.applicationName) -
Set copied
Application Bundle
to https://vk.com/apps?act=manage -> Edit App -> Settings -> App Bundle ID for iOS field -
Add the following code to AppDelegate:
- For iOS 9 and below
func application(
_ application: UIApplication,
open url: URL,
sourceApplication: String?,
annotation: Any
) -> Bool {
VK.handle(url: url, sourceApplication: sourceApplication)
return true
}
- For iOS 10 and above
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]
) -> Bool {
let app = options[.sourceApplication] as? String
VK.handle(url: url, sourceApplication: app)
return true
}
-
Authorize as described in oAuth WebView.
If user denies authorization in VK App, SwiftyVK will present oAuth dialog
If you have previously received user token, just pass it to the following method:
VK.sessions.default.logIn(rawToken: String, expires: TimeInterval)
// Start working with SwiftyVK session here
TimeInterval
is a time, after which the token will no longer be valid. Pass 0
if you want token to never expire.
SwiftyVK provides a very simple interface for interaction with VK API. All requests are performed asynchronously in a private queue by API scheduler (the scheduler sends no more than 3 requests per second by default). You can just send a request and get a response without a lot of work.
All API methods are listed here
Let's look closer to requests syntax:
The basic request calls look like VK.methodGroup.methodName().
For example, to get short info about current user:
VK.API.Users.get(.empty)
.onSuccess { /* handle and parse response */ }
.onError { /* handle error */ }
.send()
Object created with
VK.API.Users.get(.empty)
represents a request that can be sent immediately or can be configured first and sent later.
If you want to get additional fields for a user in previous example, you can set request parameters:
VK.API.Users.get([
.userId: "1",
.fields: "sex,bdate,city"
])
Use .empty
if you don't want to pass any parameters.
Requests are executed asynchronously and provide some callbacks for handling execution results:
This callback will be called when request has succeeded and returned Data
object.
You can handle and parse response using any JSON parsing method
(e.g. JSONSerialization
, Codable
, SwiftyJSON and others)
VK.API.Users.get(.empty)
.onSuccess {
let response = try JSONSerialization.jsonObject(with: $0)
}
You can throw errors in onSuccess
callback, which will cause onError
to be called with your error.
This callback will be called when request has failed for some reason. You may handle the error that was thrown in this callback.
VK.API.Users.get(.empty)
.onError {
print("Request failed with error: ($0)")
}
If you no longer need to send sheduled request (e.g. screen was popped out), just cancel it:
// `send()` function returns `Task` object which has `cancel()` function
let request = VK.API.Users.get([
.userId: "1",
.fields: "sex,bdate,city"
])
.onSuccess { print($0) }
.send()
// Cancel sheduled request.
// onSuccess callback will never be executed.
request.cancel()
SwiftyVK allows you to chain requests. If your second request needs to consume a response from the first one, just chain them together:
VK.API.Users.get(.empty)
.chain { response in
// This block will be called only
// when `users.get` method is successfully executed.
// Receives result of executing `users.get` method.
let user = try JSONDecoder().decode(User.self, from: response)
return VK.API.Messages.send([
.userId: user.id,
.message: "Hello"
])
}
.onSuccess { response in
// This block will be called only when both `users.get` and `messages.send`
// methods are successfully executed.
// `response` is a result of `messages.send` method
}
.onError { error in
// This block will be called when either `users.get` or `messages.send` methods is failed.
// Receives error of executing `users.get` or `messages.send` method.
}
.send()
You can make very long chains with SwiftyVK!
In SwiftyVK each session has default configuration for its requests.
Each request gets configuration from its session.
Configuration contains settings such as httpMethod
, attemptTimeout
and others.
You can change configuration for a single request
// Set different httpMethod only for this request
VK.API.Users.get(.empty)
.configure(with: Config(httpMethod: .POST))
or for the whole session
// Set default apiVersion value for all requests in default session
VK.sessions.default.config.apiVersion = "5.68"
You may change following configuration properties:
Property | Default | Description |
---|---|---|
httpMethod |
.GET |
HTTP method. You can use GET or POST . For big body (e.g. long message text in message.send method) use POST method. |
apiVersion |
latest version |
VK API version. By default uses latest version. If you need different version - change this value. |
language |
User system language |
Language of response. For EN Pavel Durov , for RU ะะฐะฒะตะป ะััะพะฒ . |
attemptsMaxLimit |
3 |
Maximum number of attempts to send request before returning an error. |
attemptTimeout |
10 |
Timeout in seconds of waiting for a response before returning an error. |
handleErrors |
true |
Allow to handle specific VK errors automatically by presenting a dialog to a user when authorization, captcha solving or validation is required. |
SwiftyVK provides the ability to easily upload a file to VK servers. For example:
// Get path to image file
guard let path = Bundle.main.path(forResource: "testImage", ofType: "jpg") else { return }
// Get data from image file by path
guard let data = try Data(contentsOf: URL(fileURLWithPath: path)) else { return }
// Create SwiftyVK Media representation from given data
let media = Media.image(data: data, type: .jpg)
// Upload image to server
VK.API.Upload.Photo.toWall(media, to: .user(id: "4680178"))
.onSuccess { print($0) }
.onError { print($0) }
.onProgress {
// This callback available only for uploading requests
// Use it to handle uploading status and show it to user
switch $0 {
case let .sent(current, of):
print("sent", current, "of": of)
case let .recieve(current, of):
print("recieve", current, "of": of)
}
}
.send()
Some upload requests do not immediately download files
e.g VK.API.Upload.Photo.toMessage
will return photoId
which you can use in messages.send
method.
See docs for more info.
With SwiftyVK you can interact with VK LongPoll server very easily. Just call:
VK.sessions.default.longPoll.start {
// This callback will be executed each time
// long poll client receives a set of new events
print($0)
}
Data format is described here.
LongPollEvent is an enum with associated value of type Data
in each case.
You can parse this data to JSON using your favorite parser like this:
VK.sessions.default.longPoll.start {
for event in $0 {
switch event {
case let .type1(data):
let json = JSON(data)
print(json)
default:
break
}
}
}
LongPollEvent has two special cases:
.forcedStop
- returned when LongPoll has experienced unexpected error and stop. You can restart it again.
.historyMayBeLost
- returned when LongPoll was disconnected from server for a long time
and either lpKey
or timestamp
is outdated.
You do not need to reconnect LongPoll manually, client will do it itself.
Use this case to refresh data that could have been updated while network was unavailable.
If you don't need to receive LongPoll updates anymore, just call this function:
VK.sessions.default.longPoll.stop()
With SwiftyVK can make a post to user wall. To do this, you need:
- Implement SwiftyVKDelegate
- SetUp VK application
- Present share dialog with context:
VK.sessions.default.share(
ShareContext(
text: "This post made with #SwiftyVK ๐๐ฝ",
images: [
ShareImage(data: data, type: .jpg), // JPG image representation
],
link: ShareLink(
title: "Follow the white rabbit", // Link description
url: link // URL to site
)
),
onSuccess: { /* Handle response */ },
onError: { /* Handle error */ }
Images and link are optional, text is required Sharing not available on macOS 10.10. If you want to use it, please make pull request to this repo.
I can't find some API method or parameter in library
SwiftyVK is released under the MIT license. See LICENSE for details.