Сбой приложения Swift с "непризнанным селектором, отправленным в экземпляр" на CLLocationManager

Как и во многих других вопросах, связанных с StackOverflow, я получаю ошибку unrecognized selector sent to instance при запуске моего приложения. То, что делает мой случай другим (я думаю), состоит в том, что он написан в Свифте и что общая причина здесь не причина.

В этом вопрос заключается в том, чтобы установить "Пользовательский класс" в Identity Inspector для этого представления отвечающему классу. Я проверил это, и это так (обратите внимание, что в какой-то момент я переименовал класс, но теперь он определенно установлен в "ViewController" ).

Я включаю трассировку стека ниже, а также код для ViewController.swift. Вы также можете найти весь код здесь. Мне удалось избежать этой проблемы, начав свежий, что позволило мне решить более ранний вопрос . Это новое испытание можно найти в этой ветке. Но я хочу знать, что не так, и решить эту проблему.

Некоторые думали

Один вопрос, который я не мог ответить успешно, - это то, нуждается ли CLLocationManagerDelegate в некоторых требуемых методах? Но поскольку я получил его для работы в другой отрасли, я подозреваю, что это не нужно.

2014-07-03 21:50:26.056 RowingTracker2[11416:60b] -[CLLocationManager requestWhenInUseAuthorization]: unrecognized selector sent to instance 0xa10c4a0
2014-07-03 21:50:26.059 RowingTracker2[11416:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CLLocationManager     requestWhenInUseAuthorization]: unrecognized selector sent to instance 0xa10c4a0'
*** First throw call stack:
(
    0   CoreFoundation                      0x008831e4 __exceptionPreprocess + 180
1   libobjc.A.dylib                     0x01e2a8e5 objc_exception_throw + 44
2   CoreFoundation                      0x00920243 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3   CoreFoundation                      0x0087350b ___forwarding___ + 1019
4   CoreFoundation                      0x008730ee _CF_forwarding_prep_0 + 14
5   RowingTracker2                      0x00003352 _TFC14RowingTracker214ViewController11viewDidLoadfS0_FT_T_ + 738
6   RowingTracker2                      0x000033a2 _TToFC14RowingTracker214ViewController11viewDidLoadfS0_FT_T_ + 34
7   UIKit                               0x0102f33d -[UIViewController loadViewIfRequired] + 696
8   UIKit                               0x0102f5d9 -[UIViewController view] + 35
9   UIKit                               0x00f4f267 -[UIWindow addRootViewControllerViewIfPossible] + 66
10  UIKit                               0x00f4f5ef -[UIWindow _setHidden:forced:] + 312
11  UIKit                               0x00f4f86b -[UIWindow _orderFrontWithoutMakingKey] + 49
12  UIKit                               0x00f5a3c8 -[UIWindow makeKeyAndVisible] + 65
13  UIKit                               0x00f0abc0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 2097
14  UIKit                               0x00f0f667 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
15  UIKit                               0x00f23f92 -[UIApplication handleEvent:withNewEvent:] + 3517
16  UIKit                               0x00f24555 -[UIApplication sendEvent:] + 85
17  UIKit                               0x00f11250 _UIApplicationHandleEvent + 683
18  GraphicsServices                    0x031fff02 _PurpleEventCallback + 776
19  GraphicsServices                    0x031ffa0d PurpleEventCallback + 46
20  CoreFoundation                      0x007feca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
21  CoreFoundation                      0x007fe9db __CFRunLoopDoSource1 + 523
22  CoreFoundation                      0x0082968c __CFRunLoopRun + 2156
23  CoreFoundation                      0x008289d3 CFRunLoopRunSpecific + 467
24  CoreFoundation                      0x008287eb CFRunLoopRunInMode + 123
25  UIKit                               0x00f0ed9c -[UIApplication _run] + 840
26  UIKit                               0x00f10f9b UIApplicationMain + 1225
27  RowingTracker2                      0x00008021 top_level_code + 97
28  RowingTracker2                      0x0000805b main + 43
29  libdyld.dylib                       0x024ff701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

ViewController.swift

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
    @IBOutlet var mapview: MKMapView = nil
    var locationmgr : CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        locationmgr = CLLocationManager()
        locationmgr.delegate = self
        locationmgr.requestWhenInUseAuthorization() ///< Offending line.
//        mapview.showsUserLocation = true
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Ответ 1

Этот код не будет работать на iOS 7 и ниже - согласно документам, requestWhenInUseAuthorization доступен только на iOS 8:

Доступность:

Доступно в iOS 8.0 и более поздних версиях.

Ответ 2

Поскольку метод requestWhenInUseAuthorization доступен только на iOS 8 (в соответствии с Apple Documentation), вы должны его обернуть:

Быстрый код:

if (locationmgr.respondsToSelector(Selector("requestWhenInUseAuthorization"))) {
  locationmgr.requestWhenInUseAuthorization()
}

И то же самое для Objective-C:

if ([locationmgr respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
    [locationmgr requestWhenInUseAuthorization];
}

Ответ 3

Вот что я использую для поддержки нового метода определения местоположения в iOS 7 без ошибок:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([locationManager respondsToSelector:requestSelector]) {
   [locationManager performSelector:requestSelector withObject:NULL];
}