vk-ios-sdk
vk-ios-sdk copied to clipboard
Проблема при авторизации.
При попытке авторизации открывается приложение ВК. нажимаю "Разрешить", после чего происходит возврат в приложение, и вызов метода vkSdkShouldPresent. (Происходит открытие окна авторизации в сафари). Подскажите что не так делаю. Как после возврата из приложения ВК получить сразу токен?
class RegistrationScreen: UIViewController, VKSdkDelegate, VKSdkUIDelegate {
let VK_APP_ID = "6267***"
let scope = ["email", "photos", "wall", "offline"]
let dialogsControl = DialogsControl()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func EnterButton(_ sender: Any) {
let sdkInstance = VKSdk.initialize(withAppId: self.VK_APP_ID)
sdkInstance?.register(self)
sdkInstance?.uiDelegate = self;
VKSdk.wakeUpSession(scope, complete: {(state: VKAuthorizationState, error: Error?) -> Void in
if state == .authorized {
} else {
VKSdk.authorize(self.scope)
}
return
})
}
func vkSdkShouldPresent(_ controller: UIViewController!) {
self.present(controller, animated: true, completion: nil)
}
func vkSdkAccessAuthorizationFinished(with result: VKAuthorizationResult!) {
print("token: \(result.token)")
}
func vkSdkAccessAuthorizationFinishedWithResult(result:VKAuthorizationResult?) -> Void {
print("token2: \(String(describing: result?.token))")
}
func vkSdkUserAuthorizationFailed() -> Void {
self.dialogsControl.closeAppDialog(controller: self)
}
func vkSdkAccessTokenUpdated(newToken:VKAccessToken?, oldToken:VKAccessToken?) -> Void {
}
func vkSdkAuthorizationStateUpdated(with result:VKAuthorizationResult) -> Void {
}
func vkSdkShouldPresentViewController(controller:UIViewController?) -> Void {
}
func vkSdkNeedCaptchaEnter(_ captchaError:VKError?) -> Void {
}
}
plist :
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string></string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>vk6267***</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSApplicationCategoryType</key>
<string></string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>vk</string>
<string>vk-share</string>
<string>vkauthorize</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>******</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
В AppDelegate:
private func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
VKSdk.processOpen(url as URL!, fromApplication: sourceApplication)
return true
}
У меня возникает ровно та же проблема. К сожалению выглядит так, будто в VK забросили разработку мобильных SDK.
@AlexeyMeshkov похоже на то. мне не отвечают уже два месяца...
И у меня такая же. Ни у кого так и не удалось найти решение?
@weet1 @UnumInAgro @AlexeyMeshkov @PiPhone @chipp Здравствуйте, коллеги. Решил ли кто-нибудь эту проблему ?
@UnumInAgro исправь плз заголовок на более информативный.
Тем временем в версии 1.5.1 это всё ещё не исправлено. Соответственно, если делать смену пользователя и вызывать forceLogout
, то пользователю нужно будет снова авторизовываться в Safari, что не удобно.
Попробовал сделать
func vkSdkShouldPresent(_ controller: UIViewController!) {
self.token = VKSdk.accessToken().accessToken
}
Но там ещё нет токена, получается краш((
Такая проблема может возникнуть если по какой-то причине после авторизации через приложение неверно отрабатывает этот метод sdk:

Попробуйте поставить точки останова как на скрине выше и подебажить авторизацию.
В нормальном варианте (после предоставления доступа в открывшемся приложении vk) отладчик должен остановиться внутри if
.
В моем случае я неправильно реализовал метод апделегата и вышеупомянутый метод из sdk совсем не вызывался, вследствие чего не менялся статус авторизации и sdk открывал браузер.
Сейчас мой апделегат вот так обрабатывает урлы и у меня все работает, браузер после приложения не открывается:
func application(_: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
let sourceApplication = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String
let vkSdkResult = VKSdk.processOpen(url, fromApplication: sourceApplication)
return vkSdkResult
}
@Mol0ko У меня сейчас есть и facebook и vk. Как думаешь, это правильно?
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// Facebook
if FBSDKCoreKit.ApplicationDelegate.shared.application(app, open: url, options: options) {
return true
}
// Vkontakte
if let callingAppName = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String {
if VKSdk.processOpen(url, fromApplication: callingAppName) {
return true
}
}
return false
}
@NikKovIos да, я аналогичный код использую для fb+vk
У меня баг есть (
@Mol0ko У меня сейчас есть и facebook и vk. Как думаешь, это правильно?
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // Facebook if FBSDKCoreKit.ApplicationDelegate.shared.application(app, open: url, options: options) { return true } // Vkontakte if let callingAppName = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String { if VKSdk.processOpen(url, fromApplication: callingAppName) { return true } } return false }
@NikKovIos Не разыменовывай callingAppName, processOpen принимает опциональные значения. Все должно заработать если у тебя таргет ось > 9.0
Ребят, нашёл причину. В ios 13 sourceApplication всегда nil по вопросам приватности. Просто убираем все if и делаем две строки. Одна с Facebook, другая с Vk. И в конце return true. СДК сами разруливают на что реагировать. (в коде выше тк sourceApplication == nil, в случае с фейсбуком всегда будет false, пока не обновите до 7.0.0, а вк не будет вызваться так как if let не будет получать sourceApplication). Я юзаю объединенную версию фейсбук сдк (FBSDKCore/Swift) и SwiftyVK.
Мне не помогли никакие решения.
Симптомы были такие: если приложения vk нет на девайсе, открывался webview вариант логина через метод:
vkSdkShouldPresent
После того, как пользователь жал кнопку "Разрешить" - ничего не происходило, страница перегружалась, обратно в мое приложение не возвращалось.
Если vk установлено, то оно открывалось, пользователь давал разрешение там, мое приложение снова открывалось, но токена не было и сразу открывался webview, где происходило то же самое, что и описано выше.
2 дня потратил на то, чтобы найти проблему.
В ios 13, если используете SceneDelegate (а именно так теперь по умолчанию), вызывается метод openURLContexts
, а не open url
в AppDelegate.
Решение: в SceneDelegate добавить:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
// Handle URL
VKSdk.processOpen(url, fromApplication: nil)
}
}