Cách phát hiện nếu ứng dụng đang được xây dựng cho thiết bị hoặc trình giả lập trong Swift


277

Trong Objective-C, chúng ta có thể biết liệu một ứng dụng đang được xây dựng cho thiết bị hay trình giả lập bằng cách sử dụng macro:

#if TARGET_IPHONE_SIMULATOR
    // Simulator
#else
    // Device
#endif

Đây là các macro thời gian biên dịch và không có sẵn trong thời gian chạy.

Làm thế nào tôi có thể đạt được điều tương tự trong Swift?


2
Đó không phải là cách phát hiện trình giả lập hoặc thiết bị thực trong thời gian chạy trong Objective-C. Đó là những chỉ thị của trình biên dịch dẫn đến mã khác nhau tùy thuộc vào bản dựng.
rmaddy

Cảm ơn. Tôi đã chỉnh sửa câu hỏi của tôi.
RaffAl

9
TRẢ LỜI VOTED CAO NHẤT KHÔNG PHẢI LÀ CÁCH TỐT NHẤT ĐỂ GIẢI QUYẾT VẤN ĐỀ NÀY! câu trả lời của mbelsky (hiện tại rất xa) là giải pháp duy nhất đến mà không có bất kỳ cạm bẫy nào. Ngay cả Greg Parker từ Apple cũng đề xuất làm theo cách đó : lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/ phỏng
jan.vogt

1
NGAY LẬP TỨC, NÓ CÓ THỂ ĐỂ KIẾM ĐƯỢC RẤT NHIỀU R THNG LÀ BẤT K WR SAU NÀO VỚI KIỂM TRA RUNTIME. Các đề xuất của các kỹ sư Apple thường là rác thải được suy nghĩ kém, hoặc chỉ áp dụng trong một số tình huống nhất định, do đó, bản thân có nghĩa là ít hơn không có gì.
Fattie

1
@Fattie: Sẽ rất thú vị khi biết lý do tại sao không có câu trả lời nào được thỏa mãn nhu cầu của bạn và điều bạn thực sự hy vọng bằng cách đưa ra tiền thưởng.
Martin R

Câu trả lời:


363

Cập nhật 30/01/19

Mặc dù câu trả lời này có thể hoạt động, giải pháp được đề xuất cho kiểm tra tĩnh (được làm rõ bởi một số kỹ sư của Apple) là xác định cờ trình biên dịch tùy chỉnh nhắm mục tiêu Trình mô phỏng iOS. Để biết hướng dẫn chi tiết về cách thực hiện, hãy xem câu trả lời của @ mbelsky .

Câu trả lời gốc

Nếu bạn cần kiểm tra tĩnh (ví dụ: không phải thời gian chạy nếu / khác), bạn không thể phát hiện trực tiếp trình giả lập, nhưng bạn có thể phát hiện iOS trên kiến ​​trúc máy tính để bàn như sau

#if (arch(i386) || arch(x86_64)) && os(iOS)
    ...
#endif

Sau phiên bản Swift 4.1

Sử dụng mới nhất, bây giờ trực tiếp cho tất cả trong một điều kiện cho tất cả các loại mô phỏng chỉ cần áp dụng một điều kiện -

#if targetEnvironment(simulator)
  // your simulator code
#else
  // your real device code
#endif

Để làm rõ hơn, bạn có thể kiểm tra đề xuất Swift SE-0190


Đối với phiên bản cũ hơn -

Rõ ràng, điều này là sai trên thiết bị, nhưng nó trả về đúng cho Trình mô phỏng iOS, như được chỉ định trong tài liệu :

Cấu hình xây dựng vòm (i386) trả về đúng khi mã được biên dịch cho trình giả lập iOS 32 bit.

Nếu bạn đang phát triển cho một trình giả lập khác ngoài iOS, bạn chỉ cần thay đổi ostham số: vd

Phát hiện trình giả lập watchOS

#if (arch(i386) || arch(x86_64)) && os(watchOS)
...
#endif

Phát hiện trình giả lập tvOS

#if (arch(i386) || arch(x86_64)) && os(tvOS)
...
#endif

Hoặc, thậm chí, phát hiện bất kỳ trình giả lập

#if (arch(i386) || arch(x86_64)) && (os(iOS) || os(watchOS) || os(tvOS))
...
#endif

Thay vào đó, nếu bạn ổn với kiểm tra thời gian chạy, bạn có thể kiểm tra TARGET_OS_SIMULATORbiến (hoặc TARGET_IPHONE_SIMULATORtrong iOS 8 trở xuống), đó là sự thật trên trình giả lập.

Xin lưu ý rằng điều này khác và hạn chế hơn một chút so với sử dụng cờ tiền xử lý. Chẳng hạn, bạn sẽ không thể sử dụng nó ở nơi mà a if/elsekhông hợp lệ về mặt cú pháp (ví dụ: bên ngoài phạm vi chức năng).

Ví dụ, giả sử bạn muốn có các bản nhập khác nhau trên thiết bị và trên trình giả lập. Điều này là không thể đối với kiểm tra động, trong khi đó không quan trọng bằng kiểm tra tĩnh.

#if (arch(i386) || arch(x86_64)) && os(iOS)
  import Foo
#else
  import Bar
#endif

Ngoài ra, do cờ được thay thế bằng a 0hoặc a 1bởi bộ tiền xử lý nhanh, nếu bạn trực tiếp sử dụng nó trong một if/elsebiểu thức, trình biên dịch sẽ đưa ra cảnh báo về mã không thể truy cập được.

Để khắc phục cảnh báo này, hãy xem một trong những câu trả lời khác.


1
Đọc thêm ở đây . Và để hạn chế hơn nữa, bạn có thể sử dụng arch(i386) && os(iOS).
ahruss

1
Điều này đã không làm việc cho tôi. Tôi đã phải kiểm tra cả i386 và x86_64
akaru

3
TRẢ LỜI NÀY KHÔNG PHẢI LÀ CÁCH TỐT NHẤT ĐỂ GIẢI QUYẾT VẤN ĐỀ NÀY! câu trả lời của mbelsky (hiện tại rất xa) là giải pháp duy nhất đến mà không có bất kỳ cạm bẫy nào. Ngay cả Greg Parker từ Apple cũng đề xuất làm theo cách đó : lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/ phỏng
jan.vogt 22/05/2016

2
@russbishop điều này đã chứng tỏ là lời khuyên hữu ích cho hàng trăm người cho đến nay, bù đắp cho một API bị thiếu. Thay vì chiếm đoạt câu trả lời bằng cách ký nhận xét trên đầu, chỉ cần giao tiếp. Tôi đã cập nhật câu trả lời để làm rõ đây không còn là giải pháp cập nhật nữa và tôi đã cung cấp một liên kết đến một giải pháp có vẻ đúng hơn.
Gabriele Petronella

9
Trong Swift 4.1, bạn sẽ có thể nói #if targetEnvironment(simulator):) ( github.com/apple/swift-evolution/blob/master/proposeals/ mẹo )
Hamish

172

BÊN NGOÀI ĐỂ CHUYỂN ĐỔI 4.1. Sử dụng #if targetEnvironment(simulator)thay thế. Nguồn

Để phát hiện trình giả lập trong Swift, bạn có thể sử dụng cấu hình bản dựng:

  • Xác định cấu hình này -D IOS_SIMULATOR trong Trình biên dịch Swift - Cờ tùy chỉnh> Cờ Swift khác
  • Chọn bất kỳ SDK iOS Simulator nào trong danh sách nàyDanh sách thả xuống

Bây giờ bạn có thể sử dụng câu lệnh này để phát hiện trình giả lập:

#if IOS_SIMULATOR
    print("It's an iOS Simulator")
#else
    print("It's a device")
#endif

Ngoài ra, bạn có thể mở rộng lớp UIDevice:

extension UIDevice {
    var isSimulator: Bool {
        #if IOS_SIMULATOR
            return true
        #else
            return false
        #endif
    }
}
// Example of usage: UIDevice.current.isSimulator

8
Đây nên là câu trả lời tốt nhất! Ngay cả Greg Parker từ Apple cũng đề xuất theo cách đó: list.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/ phỏng
jan.vogt

1
cập nhật sử dụng cho swift 3: UIDevice.cản.isSimulator
tylernol

1
Tôi có thể hỏi tại sao nếu tôi thêm phần này vào Bản phát hành thì nó không hoạt động?
William Hu

3
Đây là câu trả lời đúng duy nhất. Bạn cũng có thể thiết lập điều này trong xcconfigcác tệp bằng cách sử dụng OTHER_SWIFT_FLAGS = TARGET_OS_EMBEDDEDOTHER_SWIFT_FLAGS[sdk=embeddedsimulator*] = TARGET_OS_SIMULATORghi đè cho Trình mô phỏng.
Nga

1
Trên Xcode 9.2, câu trả lời này đã không được biên dịch đôi khi. Xóa "-" trước "D" đã giải quyết vấn đề cho tôi.
Blake

160

Thông tin cập nhật kể từ ngày 20 tháng 2 năm 2018

Có vẻ như @russbishop có một câu trả lời có thẩm quyền khiến câu trả lời này "không chính xác" - mặc dù nó có vẻ hoạt động trong một thời gian dài.

Phát hiện nếu ứng dụng đang được xây dựng cho thiết bị hoặc trình giả lập trong Swift

Trả lời trước

Dựa trên câu trả lời của @ WZW và ý kiến ​​của @ Pang, tôi đã tạo ra một cấu trúc tiện ích đơn giản. Giải pháp này tránh cảnh báo được tạo ra bởi câu trả lời của @ WZW.

import Foundation

struct Platform {

    static var isSimulator: Bool {
        return TARGET_OS_SIMULATOR != 0
    }

}

Ví dụ sử dụng:

if Platform.isSimulator {
    print("Running on Simulator")
}

10
Giải pháp tốt hơn nhiều so với chấp nhận. Thật vậy, nếu một ngày nào đó (mặc dù rất khó xảy ra) Apple quyết định sử dụng i386 hoặc x85_64 trên thiết bị iOS, câu trả lời được chấp nhận sẽ không hoạt động hay thậm chí nếu máy tính để bàn có được một Proc mới!
Frizlab

2
Xác nhận rằng điều này hoạt động hoàn hảo trên Xcode 7: public let IS_SIMULATOR = (TARGET_OS_SIMULATOR != 0)... điều tương tự, được đơn giản hóa. 1 nhờ
Dan Rosenstark

1
@daniel Điều này hoạt động tốt và nó thực sự đơn giản hơn giải pháp của tôi. Tuy nhiên, đáng chú ý là nó hạn chế hơn một bước tiền xử lý thực tế. Nếu bạn cần một phần mã không được đưa vào mục tiêu (ví dụ: bạn muốn chọn giữa hai lần nhập vào thời gian biên dịch), bạn phải sử dụng kiểm tra tĩnh. Tôi đã chỉnh sửa câu trả lời của mình để làm nổi bật sự khác biệt này.
Gabriele Petronella

TRẢ LỜI NÀY KHÔNG PHẢI LÀ CÁCH TỐT NHẤT ĐỂ GIẢI QUYẾT VẤN ĐỀ NÀY! câu trả lời của mbelsky (hiện tại rất xa) là giải pháp duy nhất đến mà không có bất kỳ cạm bẫy nào. Ngay cả Greg Parker từ Apple cũng đề xuất làm theo cách đó : lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/ phỏng
jan.vogt 22/05/2016

2
@Fattie TARGET_OS_SIMULATOR != 0đã có trong câu trả lời . Đó là giải pháp được đưa ra bởi Daniel. Không cần phải thêm nó một lần nữa vào một biến miễn phí, nó đã có sẵn. Nếu bạn nghĩ rằng có nó trong một cấu trúc là xấu và có nó trong một biến miễn phí thì tốt hơn là đăng một bình luận về điều này hoặc đưa ra câu trả lời của riêng bạn. Cảm ơn.
Eric Aya

69

Từ Xcode 9.3

#if targetEnvironment(simulator)

Swift hỗ trợ một mục tiêu điều kiện nền tảng mới Môi trường với một trình giả lập đối số hợp lệ duy nhất. Biên dịch có điều kiện của biểu mẫu '#if targetEn Môi trường (giả lập)' hiện có thể được sử dụng để phát hiện khi mục tiêu xây dựng là trình giả lập. Trình biên dịch Swift sẽ cố gắng phát hiện, cảnh báo và đề xuất sử dụng targetEn Môi trường (trình giả lập) khi đánh giá các điều kiện nền tảng dường như đang kiểm tra gián tiếp các môi trường giả lập, thông qua các điều kiện nền tảng os () và arch () hiện có. (SE-0190)

iOS 9+:

extension UIDevice {
    static var isSimulator: Bool {
        return NSProcessInfo.processInfo().environment["SIMULATOR_DEVICE_NAME"] != nil
    }
}

Swift 3:

extension UIDevice {
    static var isSimulator: Bool {
        return ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
    }
}

Trước iOS 9:

extension UIDevice {
    static var isSimulator: Bool {
        return UIDevice.currentDevice().model == "iPhone Simulator"
    }
}

Mục tiêu-C:

@interface UIDevice (Additions)
- (BOOL)isSimulator;
@end

@implementation UIDevice (Additions)

- (BOOL)isSimulator {
    if([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9, 0, 0}]) {
        return [NSProcessInfo processInfo].environment[@"SIMULATOR_DEVICE_NAME"] != nil;
    } else {
        return [[self model] isEqualToString:@"iPhone Simulator"];
    }
}

@end

2
So sánh các chuỗi dễ vỡ hơn khi sử dụng các hằng số xác định.
Michael Peterson

@ P1X3L5 bạn nói đúng! Nhưng tôi cho rằng phương pháp này được gọi trong chế độ gỡ lỗi - nó không thể quá vững chắc, nhưng nhanh chóng để thêm vào một dự án
HotJard

1
@GantMan cảm ơn bạn đã phản hồi. Tôi đã sửa mã
HotJard

@HotJard tốt, cái này không tạo will never be executedcảnh báo
Dannie P

59

Swift 4

Bây giờ bạn có thể sử dụng targetEnvironment(simulator)như một đối số.

#if targetEnvironment(simulator)
    // Simulator
#else
    // Device
#endif

Đã cập nhật cho Xcode 9.3


8
Điều này bây giờ nên là câu trả lời được chấp nhận. Tôi ước có một cách để SO đề xuất một câu trả lời được đề xuất mới dựa trên các bản cập nhật cho các ngôn ngữ lập trình / hệ điều hành.
tuyệt vời

4
đó là một điểm tuyệt vời @quemished - đó là một trong số ít những thất bại cơ bản của SO. Vì các hệ thống máy tính thay đổi quá nhanh, nên hầu hết mọi câu trả lời về SO đều trở nên sai theo thời gian .
Fattie

40

Hãy để tôi làm rõ một số điều ở đây:

  1. TARGET_OS_SIMULATORkhông được đặt trong mã Swift trong nhiều trường hợp; bạn có thể vô tình nhận được nó do nhập tiêu đề nhưng điều này dễ vỡ và không được hỗ trợ. Nó cũng không thể thậm chí có thể trong các khung. Đây là lý do tại sao một số người bối rối về việc liệu điều này có hoạt động trong Swift không.
  2. Tôi thực sự khuyên bạn không nên sử dụng kiến ​​trúc để thay thế cho trình giả lập.

Để thực hiện kiểm tra động:

Kiểm tra ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nillà hoàn toàn tốt.

Bạn cũng có thể lấy mô hình cơ bản được mô phỏng bằng cách kiểm tra SIMULATOR_MODEL_IDENTIFIERchuỗi nào sẽ trả về chuỗi như thế nào iPhone10,3.

Để thực hiện kiểm tra tĩnh:

Xcode 9.2 & trước đó: xác định cờ biên dịch Swift của riêng bạn (như được hiển thị trong các câu trả lời khác).

Xcode 9.3+ sử dụng điều kiện môi trường đích mới:

#if targetEnvironment(simulator)
    // for sim only
#else
    // for device
#endif

1
Có vẻ như bạn có một số thông tin mới bên trong ở đây. Rất hữu ích! Lưu ý TARGET_OS_SIMULATOR hoạt động khá lâu trong cả ứng dụng và mã khung; và nó cũng hoạt động trong Xcode 9.3 b3. Nhưng, tôi đoán đây là "tình cờ". Một loại người lập dị; bởi vì đây có vẻ là cách ít hack nhất Là nhà cung cấp mã khung có thể được biên dịch trong Xcode 9.3 trở về trước, có vẻ như chúng ta sẽ phải bọc #if targetEn Môi trường ... trong macro #if swift (> = 4.1) để tránh lỗi trình biên dịch. Hoặc tôi đoán sử dụng .... môi trường ["SIMULATOR_DEVICE_NAME"]! = Nil. Kiểm tra này có vẻ hacky hơn, IMO.
Daniel

nếu có lỗi "Điều kiện nền tảng không mong muốn (dự kiến ​​'os', 'vòm' hoặc 'swift')" khi sử dụng targetEn Môi trường (giả lập)
Zaporozhchenko Oleksandr

@Aleksandr targetEnvironmenthạ cánh trong Xcode 9.3. Bạn cần một phiên bản Xcode mới hơn.
russbishop

@russbishop làm tốt công việc này trong thời đại mới nhất - cảm ơn!
Fattie

Tôi đã gửi 250 tiền thưởng, vì câu trả lời này dường như thêm thông tin mới nhất và mới nhất - chúc mừng
Fattie

15

Những gì hoạt động với tôi vì Swift 1.0 đang kiểm tra một kiến ​​trúc khác ngoài nhánh:

#if arch(i386) || arch(x86_64)

     //simulator
#else 
     //device

#endif

14

Thời gian chạy, nhưng đơn giản hơn hầu hết các giải pháp khác ở đây:

if TARGET_OS_SIMULATOR != 0 {
    // target is current running in the simulator
}

Ngoài ra, bạn chỉ có thể gọi một hàm trợ giúp Objective-C trả về boolean sử dụng macro tiền xử lý (đặc biệt nếu bạn đã trộn trong dự án của mình).

Chỉnh sửa: Không phải là giải pháp tốt nhất, đặc biệt là đối với Xcode 9.3. Xem câu trả lời của HotJard


3
Tôi làm điều này nhưng nhận được cảnh báo trong mệnh đề khác bởi vì nó "sẽ không bao giờ được thực thi". Chúng tôi có quy tắc cảnh báo bằng không, vì vậy :-(
EricS 22/03/2017

nó sẽ hiển thị cảnh báo nhưng nó có ý nghĩa, tùy thuộc vào việc bạn có trình giả lập hoặc thiết bị được chọn để xây dựng, cảnh báo sẽ hiển thị trên phần không được thực thi, nhưng vâng, gây khó chịu cho chính sách cảnh báo bằng 0
Fonix

1
Chỉ thấy cảnh báo khi tôi sử dụng == 0thay vì != 0. Sử dụng nó như viết ở trên, ngay cả với một elsekhối sau đó, không tạo ra bất kỳ cảnh báo trong Swift 4 Xcode Version 9.2 (9C40b)
shim

Ngoài ra tôi đã thử nghiệm nó chạy trên mục tiêu giả lập cũng như thiết bị vật lý. Cũng có vẻ giống nhau trong Swift 3.2 (cùng phiên bản Xcode).
shim

Trong Xcode 9.3 + Swift 4.1 tôi chỉ nhận thấy rằng nó có cảnh báo ngay cả với! = 0. Sheesh.
shim

10

Trong các hệ thống hiện đại:

#if targetEnvironment(simulator)
    // sim
#else
    // device
#endif

Thật dễ dàng.


1
Không chắc tại sao câu đầu tiên phải "đúng" hơn câu trả lời của Daniel . - Lưu ý rằng cái thứ hai kiểm tra thời gian biên dịch. Chúc mừng năm mới!
Martin R

5

TARGET_IPHONE_SIMULATORkhông dùng nữa trong iOS 9. TARGET_OS_SIMULATORlà sự thay thế. Cũng thếTARGET_OS_EMBEDDED có sẵn.

Từ TargetCond điều kiện.h :

#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )
. . .
#define TARGET_OS_SIMULATOR         0
#define TARGET_OS_EMBEDDED          1 
#define TARGET_IPHONE_SIMULATOR     TARGET_OS_SIMULATOR /* deprecated */
#define TARGET_OS_NANO              TARGET_OS_WATCH /* deprecated */ 

1
tôi đã thử TARGET_OS_SIMULATOR nhưng không hoạt động hoặc được Xcode nhận ra trong khi TARGET_IPHONE_SIMULATOR thì không. Tôi đang xây dựng cho iOS 8.0 ở trên.
CodeOverRide

Tôi đang xem các tiêu đề iOS 9. Tôi sẽ cập nhật câu trả lời của tôi.
Nuthatch

5

Tôi hy vọng phần mở rộng này có ích.

extension UIDevice {
    static var isSimulator: Bool = {
        #if targetEnvironment(simulator)
        return true
        #else
        return false
        #endif
    }()
}

Sử dụng:

if UIDevice.isSimulator {
    print("running on simulator")
}

@ChetanKoli, tôi sẽ làm cho mã rất rõ ràng, thay vì ngắn, vì vậy nó dễ hiểu cho bất cứ ai. Không chắc tôi cảm thấy thế nào về chỉnh sửa của bạn.
Lucas Chwe

3

Trong Xcode 7.2 (và trước đó nhưng tôi chưa kiểm tra sớm hơn bao nhiêu), bạn có thể đặt cờ xây dựng nền tảng cụ thể "-D TARGET_IPHONE_SIMULATOR" cho "Bất kỳ Trình mô phỏng iOS nào".

Xem trong cài đặt xây dựng dự án trong "Trình biên dịch Swift - Cờ khách hàng" và sau đó đặt cờ trong "Cờ Swift khác". Bạn có thể đặt cờ cụ thể cho nền tảng bằng cách nhấp vào biểu tượng 'cộng' khi bạn di chuột qua cấu hình bản dựng.

Có một số lợi thế khi thực hiện theo cách này: 1) Bạn có thể sử dụng cùng một bài kiểm tra có điều kiện ("#if TARGET_IPHONE_SIMULATOR") trong mã Swift và Objective-C của bạn. 2) Bạn có thể biên dịch các biến chỉ áp dụng cho mỗi bản dựng.

Ảnh chụp màn hình cài đặt Xcode



1

Tôi đã sử dụng mã dưới đây trong Swift 3

if TARGET_IPHONE_SIMULATOR == 1 {
    //simulator
} else {
    //device
}

1
Tôi làm điều này nhưng nhận được cảnh báo trong mệnh đề khác bởi vì nó "sẽ không bao giờ được thực thi". Chúng tôi có một quy tắc cảnh báo bằng không, vì vậy
grrrr

Nó sẽ hiển thị cảnh báo bất cứ khi nào bạn đang cố chạy với thiết bị, nếu bạn được chọn giả lập để chạy, nó sẽ không hiển thị cảnh báo.
ak_ninan

1
nó không được chấp nhận
rcmstark

1

Swift 4:

Hiện tại, tôi thích sử dụng lớp ProcessInfo để biết thiết bị có phải là trình giả lập hay không và loại thiết bị nào đang được sử dụng:

if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
            print("yes is a simulator :\(simModelCode)")
}

Nhưng, như bạn đã biết, simModelCodekhông phải là một mã thoải mái để hiểu ngay lập tức loại trình giả lập nào đã được tung ra, nếu bạn cần, bạn có thể thử xem câu trả lời SO khác này để xác định kiểu iPhone / thiết bị hiện tại và để có nhiều người hơn chuỗi có thể đọc được.


1

Dưới đây là ví dụ Xcode 11 Swift dựa trên câu trả lời tuyệt vời của HotJard ở trên , điều này cũng thêm isDeviceBool và sử dụng SIMULATOR_UDIDthay vì tên. Các bài tập biến được thực hiện trên mỗi dòng để bạn có thể dễ dàng kiểm tra chúng hơn trong trình gỡ lỗi nếu bạn chọn.

import Foundation

// Extensions to UIDevice based on ProcessInfo.processInfo.environment keys
// to determine if the app is running on an actual device or the Simulator.

@objc extension UIDevice {
    static var isSimulator: Bool {
        let environment = ProcessInfo.processInfo.environment
        let isSimulator = environment["SIMULATOR_UDID"] != nil
        return isSimulator
    }

    static var isDevice: Bool {
        let environment = ProcessInfo.processInfo.environment
        let isDevice = environment["SIMULATOR_UDID"] == nil
        return isDevice
    }
}

Ngoài ra còn có mục từ điển DTPlatformNamenên chứa simulator.


0

Sử dụng mã dưới đây:

#if targetEnvironment(simulator)
   // Simulator
#else
   // Device
#endif

Hoạt động cho Swift 4Xcode 9.4.1


0

Xcode 11, Swift 5

    #if !targetEnvironment(macCatalyst)
    #if targetEnvironment(simulator)
        true
    #else
        false        
    #endif
    #endif

0

Ngoài các câu trả lời khác.

Trong Objective-c, chỉ cần đảm bảo bạn đã bao gồm TargetCond điều kiện .

#include <TargetConditionals.h>

trước khi sử dụng TARGET_OS_SIMULATOR.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.