2014-11-03 23 views
8

Tôi muốn phát hiện xem người dùng đã bật Giảm độ trong suốt hay chưa. Nó đơn giản bạn chỉ cần gọi func UIAccessibilityIsReduceMotionEnabled() và nó trả về một Bool. Nhưng ứng dụng của tôi nhắm vào iOS 7 và 8 và chức năng này không có sẵn trên iOS 7.Kiểm tra xem chức năng có sẵn trong Swift không?

Trong Objective-C, đây là cách tôi đã kiểm tra để xem nếu chức năng tồn tại:

if (UIAccessibilityIsReduceMotionEnabled != NULL) { } 

Trong Swift , Tôi không thể tìm ra cách kiểm tra xem nó có tồn tại hay không. Theo this answer, bạn có thể chỉ cần sử dụng chuỗi tùy chọn và nếu đó là nil thì nó không tồn tại, nhưng điều đó bị hạn chế đối với giao thức Obj-C rõ ràng. Xcode 6.1 không thích điều này:

let reduceMotionDetectionIsAvailable = UIAccessibilityIsReduceMotionEnabled?() 

Bạn muốn xóa?. Và tất nhiên nếu bạn làm như vậy nó sẽ sụp đổ trên iOS 7 vì chức năng đó không tồn tại.

Cách thích hợp để kiểm tra xem các loại chức năng này có tồn tại không?

+0

ngoặc sau khi một biểu hiện chức năng gọi hàm. Điều gì sẽ xảy ra nếu bạn bỏ chúng ra? – outis

+0

Nếu bạn rời khỏi() nó nói cùng một điều - xóa?: 'Toán tử của postfix '?' nên có loại tùy chọn; loại là '() -> Bool''. Ngoài ra nếu bạn di chuyển? sau dấu(), tất cả đều là thông báo lỗi tương tự. – Joey

+0

Tôi nghi ngờ nó thực sự chưa có sẵn. Từ sự hiểu biết của tôi, chuỗi tùy chọn được sử dụng cho các biến lớp. 'UIAccessibilityIsReduceMotionEnabled' giống như hàm tĩnh – Peter

Trả lời

7

Kiểm tra thích hợp về tính khả dụng đã được thêm vào trong Swift 2. Điều này được khuyến nghị so với các tùy chọn khác được đề cập ở đây.

var shouldApplyMotionEffects = true 
if #available(iOS 8.0, *) { 
    shouldApplyMotionEffects = !UIAccessibilityIsReduceMotionEnabled() 
} 
2

Bạn có thể kiểm tra để xem nếu bạn đang chạy trong iOS 8 hoặc cao hơn -

var reduceMotionEnabled = false 
if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 8, minorVersion: 0, patchVersion: 0)) { 
    reduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled() 
} 

Tôi không nghĩ có một cách khác để nói. Vì vậy, về mặt lý thuyết, nếu bạn có thể kiểm tra, cố truy cập tên chức năng mà không cần () sẽ cung cấp cho bạn nil trong iOS 7 và chức năng () -> Bool trong iOS 8. Tuy nhiên, để điều đó xảy ra, cần phải xác định UIAccessibilityIsReduceMotionEnabled(() -> Bool)?, không phải như vậy. Kiểm tra nó ra sản lượng một trường hợp chức năng trong cả hai phiên bản iOS mà bị treo nếu gọi trong iOS 7:

Cách duy nhất tôi có thể thấy để làm điều đó mà không cần thử nghiệm phiên bản chỉ đơn giản là để xác định chức năng C của riêng bạn để kiểm tra trong tập tin tiêu đề cầu nối của bạn, và gọi đó là:

// ObjC 
static inline BOOL reduceMotionDetectionIsAvailable() { 
    return (UIAccessibilityIsReduceMotionEnabled != NULL); 
} 

// Swift 
var reduceMotionEnabled = false 
if reduceMotionDetectionIsAvailable() { 
    reduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled() 
} 
+0

Vâng, đó là một cách để làm điều đó. Apple sẽ khuyên bạn nên chống lại điều đó mặc dù và có trong quá khứ trong các phiên WWDC. Có nhiều lần bạn cần phải phát hiện nếu một chức năng tồn tại, đặc biệt là khi hỗ trợ nhiều hệ điều hành. Đây có phải là thứ không tồn tại trong Swift không? Nghe có vẻ điên. – Joey

+0

Điên thực sự. Xem cập nhật. –

+1

Cảm ơn, lòng tốt thật khủng khiếp. : P Thời gian để gửi yêu cầu nâng cao! Tôi sẽ không sử dụng Obj-C, ứng dụng này là Swift thuần túy. – Joey

5

Nếu bạn đang okay với việc một chút táo bạo, bạn luôn có thể mở nhị phân UIKit bằng cách sử dụng bộ nạp thư viện và xem nếu nó có thể giải quyết các biểu tượng:

let uikitbundle = NSBundle(forClass: UIView.self) 
let uikit = dlopen(uikitbundle.executablePath!, RTLD_LAZY) 
let handle = dlsym(uikit, "UIAccessibilityIsReduceMotionEnabled") 
if handle == nil { 
    println("Not available!") 
} else { 
    println("Available!") 
} 

Các cuộc gọi dlopendlsym có thể khá tốn kém mặc dù vậy tôi khuyên bạn nên giữ số dlopen xử lý mở cho cuộc sống của ứng dụng và lưu trữ ở đâu đó do cố gắng dlsym. Nếu không, hãy đảm bảo rằng bạn dlclose.

Theo như tôi biết đây là AppStore an toàn, vì UIAccessibilityIsReduceMotionEnabled là API công khai.

+0

đẹp nhất @aethe – NSTJ

0

Từ các tài liệu của Apple Developer (Using Swift with Cocoa and Objective-C (Swift 3) > Interoperability > Adopting Cocoa Design Patterns > API Availability):

đang Swift có thể sử dụng sự sẵn có của các API như một điều kiện tại thời gian chạy.Có thể sử dụng kiểm tra tính sẵn có thay cho điều kiện trong câu lệnh kiểm soát luồng , chẳng hạn như tuyên bố if, guard hoặc while .

Lấy ví dụ trước, bạn có thể kiểm tra tính sẵn sàng trong một tuyên bố if gọi requestWhenInUseAuthorization() chỉ khi phương pháp hiện có sẵn tại thời gian chạy:

let locationManager = CLLocationManager() 
if #available(iOS 8.0, macOS 10.10, *) { 
    locationManager.requestWhenInUseAuthorization() 
} 

Ngoài ra, bạn có thể kiểm tra tính sẵn sàng trong một tuyên bố guard , thoát khỏi phạm vi trừ khi mục tiêu hiện tại đáp ứng các yêu cầu được chỉ định là . Cách tiếp cận này đơn giản hóa logic xử lý các khả năng nền tảng khác nhau.

let locationManager = CLLocationManager() 
guard #available(iOS 8.0, macOS 10.10, *) else { return } 
locationManager.requestWhenInUseAuthorization() 

Mỗi đối số nền tảng bao gồm một trong các tên nền tảng được liệt kê bên dưới, theo sau là số phiên bản tương ứng. Đối số cuối cùng là một dấu hoa thị (*), được sử dụng để xử lý các nền tảng tiềm năng trong tương lai.

vBulletin Tên:

  • iOS
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension
Các vấn đề liên quan