Тема 1: EXC_BAD_ACCESS (код = 1, адрес = 0x0) При работе в Swift, пытаясь войти в Spotify

Код:

//
//  AppDelegate.swift
//  SplitterSwift3
//
//  Created by VideoLabN on 4/8/18.
//  Copyright © 2018 VideoLabN. All rights reserved.
//

import UIKit
import AWSAuthCore
import AWSMobileClient
import AWSCore


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
var auth = SPTAuth()
// Add a AWSMobileClient call in application:open url
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {

    // called when user signs into spotify. Session data saved into user defaults, then notification posted to call updateAfterFirstLogin in ViewController.swift. Modeled off recommneded auth flow suggested by Spotify documentation


    if auth.canHandle(auth.redirectURL) {
        auth.handleAuthCallback(withTriggeredAuthURL: url, callback: { (error, session) in


            if error != nil {
                print("error!")
            }
            let userDefaults = UserDefaults.standard
            let sessionData = NSKeyedArchiver.archivedData(withRootObject: session)
            print(sessionData)
            userDefaults.set(sessionData, forKey: "SpotifySession")
            userDefaults.synchronize()
            NotificationCenter.default.post(name: Notification.Name(rawValue: "loginSuccessfull"), object: nil)
        })
        return true
    }

    return false


}

 //Add a AWSMobileClient call in application:didFinishLaunching
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions:
    [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    return AWSMobileClient.sharedInstance().interceptApplication(
        application, didFinishLaunchingWithOptions:
        launchOptions)
}

}


//
//  ViewController.swift
//  SplitterSwift3
//
//  Created by VideoLabN on 4/8/18.
//  Copyright © 2018 VideoLabN. All rights reserved.
//

import UIKit
import SafariServices
import AVFoundation
import AWSAuthCore
import AWSAuthUI


class ViewController: UIViewController, SPTAudioStreamingPlaybackDelegate, SPTAudioStreamingDelegate  {

// Variables
var auth = SPTAuth.defaultInstance()!
var session:SPTSession!

// Initialzed in either updateAfterFirstLogin: (if first time login) or in viewDidLoad (when there is a check for a session object in User Defaults
var player: SPTAudioStreamingController?
var loginUrl: URL?

// Outlets
@IBOutlet weak var loginSpotify: UIButton!
@IBOutlet weak var loginSplitter: UIButton!
@IBOutlet weak var testLabel: UILabel!

override func viewDidLoad() {
    print("test")
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.setup()
    //NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateAfterFirstLogin, name: NSNotification.Name(rawValue: "loginSuccessfull"), object: nil)
    //self.updateAfterFirstLogin()

}

func setup () {

    // insert redirect your url and client ID below
    let redirectURL = "splitter-app://callback" // put your redirect URL here
    let clientID = "207ce42c908f42e485c540be11720888" // put your client ID here
    auth.redirectURL     = URL(string: redirectURL)
    auth.clientID        = "client id goes here"
    auth.requestedScopes = [SPTAuthStreamingScope, SPTAuthPlaylistReadPrivateScope, SPTAuthPlaylistModifyPublicScope, SPTAuthPlaylistModifyPrivateScope]
    loginUrl = auth.spotifyWebAuthenticationURL()
    //print("test")


}
func initializePlayer(authSession:SPTSession){
    if self.player == nil {
        self.player = SPTAudioStreamingController.sharedInstance()
        self.player!.playbackDelegate = self
        self.player!.delegate = self
        try! player!.start(withClientId: auth.clientID)
        self.player!.login(withAccessToken: authSession.accessToken)
    }
}
@objc func updateAfterFirstLogin ()  {
    loginSpotify.isHidden = true
    let userDefaults = UserDefaults.standard
    if let sessionObj:AnyObject = userDefaults.object(forKey: "SpotifySession") as AnyObject? {
        let sessionDataObj = sessionObj as! Data
        let firstTimeSession = NSKeyedUnarchiver.unarchiveObject(with: sessionDataObj) as! SPTSession
        self.session = firstTimeSession
        initializePlayer(authSession: session)
    }
}







func audioStreamingDidLogin(_ audioStreaming: SPTAudioStreamingController!) {
    // after a user authenticates a session, the SPTAudioStreamingController is then initialized and this method called
    print("logged in")
//        
self.player?.playSpotifyURI("spotify:track:58s6EuEYJdlb0kO7awm3Vp", 
startingWith: 0, startingWithPosition: 0, callback: { (error) in
//            if (error != nil) {
//                print("playing!")
//            }
//
//        })

    }
@IBAction func spotifyButtonPressed(_ sender: Any) {
    let svc = SFSafariViewController(url: loginUrl!)
    self.present(svc, animated: true, completion: nil)
    //UIApplication.shared.open(loginUrl!, options: [:])


}

}

Приложение прекрасно компилируется и запускается на симуляторе iPhone. Кнопка для входа в Spotify работает и открывает экземпляр Safari, предлагая пользователю войти в Spotify.

После того, как пользователь вошел в систему, он запрашивает разрешения. Как только пользователь принимает разрешения, приложение вылетает в строке 16 класса appDelegate с этой ошибкой:

Поток 1: EXC_BAD_ACCESS (код = 1, адрес = 0x0).

Я читал об этом в Интернете, и люди говорят, что это эквивалентно исключению нулевого указателя, но я не могу найти причину этой ошибки. Кто-нибудь может найти ошибку?

Редактировать: Спасибо тем, кто ответил! Вот мой вывод консоли:

objc[19082]: класс VCWeakObjectHolder реализован как в /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/ Библиотека/PrivateFrameworks/AVConference.framework/Frameworks/ViceroyTrace.framework/ViceroyTrace (0x12b9174d0) и /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/ Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/AVConference.framework/AVConference (0x12aa65e38). Один из двух будет использован. Какой из них не определено. test 2018-04-15 13:33:50.341600-0400 SplitterSwift3[19082:1059086] [AXRun-PID] Клиент запрашивает отмену приостановки PID:-1 Имя: 2018-04-15 13:33:50.441522-0400 SplitterSwift3[19082: 1058985] [MC] Контейнер системной группы для пути systemgroup.com.apple.configurationprofiles: /Users/videolabn/Library/Developer/CoreSimulator/Devices/CEC32A65-63E0-4499-AB25-6BD13A7AE013/data/Containers/Shared/SystemGroup/systemgroup .com.apple.configurationprofiles 15-04-2018 13:33:50.442782-0400 SplitterSwift3[19082:1058985] [MC] Чтение из частных эффективных пользовательских настроек. 2018-04-15 13:33:50.536744-0400 SplitterSwift3[19082:1058985] [Приложение], если мы находимся в реальном обработчике перед фиксацией, мы не можем фактически добавить какие-либо новые ограничения из-за ограничений CA (lldb)


person endlessVinyl    schedule 15.04.2018    source источник
comment
В какой строке он остановится, если вы установите точку останова исключения?   -  person Michael Hulet    schedule 15.04.2018
comment
У вас есть полный журнал сбоев в консоли? Потому что я вижу несколько! (принудительное распаковывание), что может вызвать эту проблему или что-то еще.   -  person Larme    schedule 15.04.2018
comment
Спасибо за комментарий @Larme! Я нуб, как мне найти полный журнал сбоев?   -  person endlessVinyl    schedule 15.04.2018
comment
Спасибо за комментарий @MichaelHulet! Я установил общую точку останова исключения, но все равно получаю ту же ошибку в той же строке! Я делаю что-то не так или у меня просто такая же ошибка?   -  person endlessVinyl    schedule 15.04.2018
comment
Откуда мы должны знать, что такое строка 16. Считать с начала файла, считать с начала метода, включать пустые строки, не включать пустые строки, включать комментарии, не включать комментарии при подсчете... Что такое строка 16?   -  person Gruntcakes    schedule 15.04.2018
comment
Добро пожаловать в СО. Пожалуйста, научитесь правильно форматировать и корректировать свои вопросы. См. также здесь: stackoverflow.com/help/how-to-ask   -  person petezurich    schedule 15.04.2018
comment
извините за это @Gruntcakes! Строка 16 — это объявление класса. Я считал все, включая комментарии и разрывы строк.   -  person endlessVinyl    schedule 15.04.2018


Ответы (1)


Функция UIApplicationDelegate application(_:open:sourceApplication:annotation:) устарела в iOS 10.

Начиная с iOS 11.3 кажется, что приложения, использующие эту функцию, будут аварийно завершать работу при ее вызове. Решение состоит в том, чтобы вместо этого использовать замену application(_:open:options:).

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

    if auth.canHandle(auth.redirectURL) {
        auth.handleAuthCallback(withTriggeredAuthURL: url, callback: { (error, session) in
            if error != nil {
                print("error!")
            }
            let userDefaults = UserDefaults.standard
            let sessionData = NSKeyedArchiver.archivedData(withRootObject: session)
            print(sessionData)
            userDefaults.set(sessionData, forKey: "SpotifySession")
            NotificationCenter.default.post(name: Notification.Name(rawValue: "loginSuccessfull"), object: nil)
        })
        return true
    }
    return false  
}

Также нет необходимости звонить synchronize для UserDefaults

person Paulw11    schedule 15.04.2018
comment
Спасибо за помощь! Я внедрил это изменение, и вместо того, чтобы получить сообщение об ошибке, когда я нажимаю «ОК» на экране предварительной проверки Spotify, ничего не происходит. Он просто останавливается. Однако приложение не дает сбоев, поэтому проблема может заключаться в том, как я реализовал API-интерфейс Spotify. - person endlessVinyl; 16.04.2018
comment
Он возвращается в ваше приложение? Делает ли ваше приложение что-то, когда публикуется уведомление loginSuccessfull? - проверьте правильность написания названия уведомления, которое вы наблюдаете; в конце уведомления, которое вы публикуете, есть двойная буква l. Лучше создавать имена уведомлений в одном месте и ссылаться на них, а не использовать буквальную строку, в которой могут возникнуть несоответствия. - person Paulw11; 16.04.2018