We’re encountering issues with a system extension that subscribes to multiple events. Some users are experiencing performance problems when running our extension alongside other system extensions like Microsoft Defender and Crowdstrike, which seem to generate a high volume of events. However, on certain Macs with an identical setup, there are no performance issues, making it difficult to pinpoint the cause.
Has anyone found ways to improve compatibility with other system extensions? Currently, we’re ignoring and caching events from other extensions to avoid unnecessary processing.
The specific ES events contributing to the issue seem to be:
• ES_EVENT_TYPE_AUTH_EXEC
• ES_EVENT_TYPE_AUTH_OPEN
I realize this is a broad question, but the documentation for endpoint security extensions is quite limited. Any insights or suggestions would be greatly appreciated!
Core OS
RSS for tagExplore the core architecture of the operating system, including the kernel, memory management, and process scheduling.
Post
Replies
Boosts
Views
Activity
Problem: One of my QA Device crash while launch the iOS 15.5.
Background: Previously, I update my os to macOS Sequoia & update my Xcode to 16 Release Candidate. Previously when the app was build in Xcode 15.4, it run/launch perfectly, but it seems the app is crash below iOS 15.5
---- HERE THE CRASH LOG ------
Incident Identifier: 6E80706A-C8FA-4E6F-8F14-5746E6CA5129
Hardware Model: iPhone13,3
Process: Runner [79635]
Path: /private/var/containers/Bundle/Application/ED368AA9-3A69-45CE-89CA-438440BB8781/Runner.app/Runner
Identifier: -
Version: 1.0.7 (3273)
AppStoreTools: 16B39
AppVariant: 1:iPhone13,3:15
Beta: YES
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: - [872]
Date/Time: 2024-10-29 08:56:13.5458 +0700
Launch Time: 2024-10-29 08:56:13.4479 +0700
OS Version: iPhone OS 15.5 (19F77)
Release Type: User
Baseband Version: 2.54.02
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: DYLD 4 Symbol missing
Symbol not found: _objc_claimAutoreleasedReturnValue
Referenced from: /Volumes/VOLUME/*/Runner.app/Frameworks/KSCrashCore.framework/KSCrashCore
Expected in: /usr/lib/libobjc.A.dylib
(terminated at launch; ignore backtrace)
Triggered by Thread: 0
Thread 0 Crashed:
0 dyld 0x00000001025007a0 __abort_with_payload + 8 (:-1)
1 dyld 0x0000000102506388 abort_with_payload_wrapper_internal + 104 (terminate_with_reason.c:102)
2 dyld 0x00000001025063bc abort_with_payload + 16 (terminate_with_reason.c:124)
3 dyld 0x00000001024d6828 dyld4::halt(char const*) + 328 (DyldProcessConfig.cpp:2067)
4 dyld 0x00000001024d3960 dyld4::prepare(dyld4::APIs&, dyld3::MachOAnalyzer const*) + 3560 (dyldMain.cpp:0)
5 dyld 0x00000001024d1cc4 start + 488 (dyldMain.cpp:864)
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000006 x1: 0x0000000000000004 x2: 0x000000016eee1690 x3: 0x00000000000000d8
x4: 0x000000016eee1290 x5: 0x0000000000000000 x6: 0x0000000000000000 x7: 0x000000016eee0cd0
x8: 0x0000000000000020 x9: 0x0000000000000009 x10: 0x0000000000000001 x11: 0x000000000000000a
x12: 0x0000000000000000 x13: 0x0000000000000037 x14: 0x00000002301c9625 x15: 0x0000000000000002
x16: 0x0000000000000209 x17: 0x00000001024fae54 x18: 0x0000000000000000 x19: 0x0000000000000000
x20: 0x000000016eee1290 x21: 0x00000000000000d8 x22: 0x000000016eee1690 x23: 0x0000000000000004
x24: 0x0000000000000006 x25: 0x000000016eee3728 x26: 0x0000000000000001 x27: 0x000000016eee3590
x28: 0x0000000000000000 fp: 0x000000016eee1260 lr: 0x0000000102506388
sp: 0x000000016eee1220 pc: 0x00000001025007a0 cpsr: 0x1000
esr: 0x56000080 Address size fault
Binary Images:
0x1024b8000 - 0x10250ffff dyld arm64e <7c9c7851823738a7b1eb9cd2deb4b746> /usr/lib/dyld
EOF
Hi,
for https://developer.apple.com/documentation/corenfc/cardsession/, is the Select PPSE APDU forwarded to the 3rd party payment app for processing?
The use case is to provide a specific list of AIDs controlled by the app rather than all the AIDs registered under the app's entitlement.
Supplying a complete copy the error from my log file below. Can someone tell me what changed in Sequoia that would be causing this error? If there a work around? Is there something I can do to correct this?
Thanks,
Ken
10.953 (I) DatabaseSaver.swift:207 phase1_startReadingRemoteDatabase(timeout:) Checking original database for out-of-band changes
10.975 (D) DatabaseSaver.swift:251 phase2_startResolvingConflict(localData:remoteData:remoteURL:) Original file is safe to overwrite.
10.975 (I) DatabaseSaver.swift:285 phase3_startWritingRemoteDatabase(resolvedData:) Writing database file
15.178 (E) LocalDataSource.swift:85 write(_:to:fileProvider:timeout:queue:completionQueue:completion:) Failed to write file [message: You don’t have permission to save the file “MyPasswords.kdbx” in the folder “Downloads”.
15.179 (E) FileAccessError.swift:217 make(from:fileName:fileProvider:) Failed to access the file [fileProvider: com.apple.FileProvider.LocalStorage, systemError: Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file “MyPasswords.kdbx” in the folder “Downloads”." UserInfo={NSUnderlyingError=0x6000014a0270 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}, NSFilePath=/Users/user123/Library/Mobile Documents/comappleCloudDocs/Downloads/MyPasswords.kdbx, NSURL=file:///Users/user123/Library/Mobile%20Documents/comappleCloudDocs/Downloads/MyPasswords.kdbx}]
15.179 (E) DatabaseSaver.swift:309 phase3_startWritingRemoteDatabase(resolvedData:) Failed to write database, cancelling
15.179 (E) DatabaseSaver.swift:432 finalize(withError:) Failed to open remote file [message: Cannot save file (macOS)]
I try to mix content filter and endpoint security in one system extension, but get error below when the program invoke es_new_client(returned ES_NEW_CLIENTRESULT_ERR_INTERNAL).
Failed to open services: 0xe00002e2: Caller was denied connecting to the ES subsystem, possibly due to a sandbox violation.
how to solve this error while keeping two functionalities in one system extension?
or I have to seperate them?
I'm encountering an issue where a specific BLE device (a Telematics Control Unit) is being discovered by some iPhone models but not others, all running the same iOS version (18.0.1).
Here's the breakdown:
Successful discovery: iPhone 11, iPhone 14 Plus, iPhone 6s
No discovery: iPhone 13, iPhone 12 mini
Firmware: The TCU firmware is up-to-date.
BLE: Bluetooth is enabled on all devices.
I've tried basic troubleshooting like restarting devices and resetting network settings, but the issue persists. Could this be related to differences in Bluetooth chipsets or antenna designs between iPhone models, even with the same iOS version? Are there any known compatibility issues between this TCU and specific iPhone models?
Any insights or suggestions for further debugging issue would be greatly appreciated!
MTRAttributeIDType is giving 'unknown cluster' results for every combination of cluster and accessory.
for the same clusters MTRClusterNameForID gives the expected result.
hello,
I would like to run benchmarks on p-cores vs e-cores,
I suspect a difference of more than 50%
is it possible to choose your processor (P or E) to run your program?
nice day
I have seen these 2 articles that I have attached below that seem to offer some assistance. But is there a more modern way to share secured information between macOS users on same machine?
Entitlements
File System Protections
STEPS TO REPRODUCE
do
{
let baseDir = try fileMgr.url(for: .applicationSupportDirectory, in: .localDomainMask, appropriateFor: nil, create: true).appendingPathComponent("com.MyCompany.AppName", conformingTo: .directory)
try fileMgr.createDirectory(at: baseDir, withIntermediateDirectories: true, attributes: nil)
}
catch
{
Swift.print("ERROR: can't create baseDir \(baseDir)")
exit(0)
}
Hi, I encounter unexpected behavior from the FileWrapper updates that occurs when I remove file using FileManager.removeItem
If I first remove a file from the directory, then create NSFileWrapper instance, I get unexpected values from calls to matchesContents(of:)
import Foundation
let copyURL = URL(filePath: "/Users/marcinkrzyzanowski/Downloads/filewrappertest.test/COPY.png")
// THIS OPERATION BREAKS IT. REMOVE IT TO WORK AS EXPECTED
try! FileManager().removeItem(at: copyURL)
let dirURL = URL(filePath: "/Users/marcinkrzyzanowski/Downloads/filewrappertest.test")
let fw = try FileWrapper(url: dirURL)
fw.fileWrappers // ["IMG_0736.png"]
try FileManager.default.copyItem(at: URL(filePath: "/Users/marcinkrzyzanowski/Downloads/filewrappertest.test/IMG_0736.png"), to: copyURL)
fw.fileWrappers // ["IMG_0736.png"]
fw.matchesContents(of: dirURL) // true (expected: false)
try fw.read(from: dirURL)
fw.fileWrappers! // ["COPY.png", "IMG_0736.png"]
fw.matchesContents(of: dirURL) // true
I don't understand why the "FileManager.removeItem" affects the NSFileWrapper behavior in such a way. It does not change even when I add a delay after removeItem. Any idea?
I work on EdenFS, an open-source Virtual Filesystem that runs on macOS, Linux, and Windows. My team is very interested in using FSKit as the basis for EdenFS on macOS, but have found the documentation to be lacking and contains some mixed messaging on the future of FSKit. Below are a few questions that don’t seem to be fully covered by the current documentation:
Does FSKit support process attribution? Each FUSE request provides a requester Process ID (and other information) through the fuse_in_header structure. Does FSKit pass similar information along for each request?
Does the reclaimItem API function similarly to FUSE’s forget operation? If not, what are the differences? See #1 below for why forget/reclaimItem matters to us.
Is Apple committed to releasing and supporting FSKit? Is there any timeline for release that we can plan around?
Does FSKit have known performance/scalability limitations? We provide alternative methods that clients can use to make bulk requests to EdenFS, but some clients will necessarily be unable to use those and stress the default filesystem APIs. Throughput (on the order of tens of thousands of filesystem requests per minute) and request size are the main concerns, followed closely by directory size restrictions.
Why we’re interested in FSKit
As mentioned above, my team supports EdenFS on 3 platforms. On Linux, we utilize FUSE; on Windows, we utilize ProjectedFS; and on macOS, we’ve utilized a few different solutions in the past. We first utilized the macFUSE kext, which was great while it lasted. Due to (understandable) changes in supporting kernel extensions, we were forced to move to NFS version 3. NFS has been lackluster in comparison (and our initial investigations show that NFS version 4(.2) would be similar). We have had numerous scalability and reliability issues, some listed below:
NFS does not provide a forget API similar to FUSE. EdenFS is forced to remember all file handles that have been loaded because the kernel never informs us when all references to that file handle have been dropped. We can hackily infer that a file handle should never be referenced again in some cases, but a large number of file handles end up being remembered forever. Many of our algorithms scale with the number of file handles that Eden has to consider, and therefore performance issues are inevitable after some time.
NFS does not provide information about clients (requesters). We cannot tell which processes are sending EdenFS requests. This attribution is important due to issue #1. We are forced to work with tool owners to modify their applications to be VFS-friendly. If we can’t track down which tools are behaving poorly, they will continue to load excess file handles and cause performance issues.
NFS “Server connections interrupted:” dialog during heavy load. Under heavy load, either EdenFS or system-wide, our users experience this dialog pop-up and are confused as to how they should respond (Ignore or Disconnect All). They become blocked in their work, and will be further blocked if they click “Disconnect All” as that unmounts their EdenFS mount. This forces them to restart EdenFS or reboot their laptop to remediate the issue.
The above issues make us extremely motivated to use FSKit and partner with Apple to flesh out the final version of the FSKit API. Our use case likely mirrors what other user-space filesystems will be looking for in the FSKit API (albeit at a larger scale than most), and we’re willing to collaborate to work out any issues in the current FSKit offerings.
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: SIGNAL 6 Abort trap: 6
Terminating Process: APPX_MOBILE[14375]
Triggered by Thread: 8
Application Specific Information:
abort() called
Thread 8 name: com.facebook.react.JavaScript
Thread 8 Crashed:
0 libsystem_kernel.dylib 0x1d9927274 __pthread_kill + 8
1 libsystem_pthread.dylib 0x210e5aef8 pthread_kill + 268
2 libsystem_c.dylib 0x19183bad8 abort + 128
3 libsystem_malloc.dylib 0x199cb1c4c malloc_vreport + 896
4 libsystem_malloc.dylib 0x199cb18bc malloc_report + 64
5 libsystem_malloc.dylib 0x199cb0e94 find_zone_and_free + 528
6 APPX_MOBILE 0x1036f6018 0x102870000 + 15228952
7 APPX_MOBILE 0x1036f5f58 0x102870000 + 15228760
8 APPX_MOBILE 0x1036f9288 0x102870000 + 15241864
9 APPX_MOBILE 0x1036f8a4c 0x102870000 + 15239756
10 APPX_MOBILE 0x103746820 0x102870000 + 15558688
11 APPX_MOBILE 0x1037468f4 0x102870000 + 15558900
12 APPX_MOBILE 0x10374b4c8 0x102870000 + 15578312
13 APPX_MOBILE 0x1039ccfb4 0x102870000 + 18206644
14 APPX_MOBILE 0x103cb59c8 0x102870000 + 21256648
15 APPX_MOBILE 0x103cb57d0 0x102870000 + 21256144
16 APPX_MOBILE 0x103cb3d2c 0x102870000 + 21249324
17 hermes 0x104de11f0 facebook::hermes::HermesRuntimeImpl::JsiProxy::get(hermes::vm::SymbolID) + 96
18 hermes 0x104e10e68 hermes::vm::JSObject::getComputedWithReceiver_RJS(hermes::vm::Handlehermes::vm::JSObject, hermes::vm::Runtime&, hermes::vm::Handlehermes::vm::HermesValue, hermes::vm::Handlehermes::vm::HermesValue) + 732
19 hermes 0x104e004cc hermes::vm::CallResult<hermes::vm::HermesValue, (hermes::vm::detail::CallResultSpecialize)2> hermes::vm::Interpreter::interpretFunction<false, false>(hermes::vm::Runtime&, hermes::vm::InterpreterState&) + 10480
20 hermes 0x104dfdbb4 hermes::vm::Runtime::interpretFunctionImpl(hermes::vm::CodeBlock*) + 52
21 hermes 0x104e2e5d4 hermes::vm::Runtime::runBytecode(std::__1::shared_ptrhermes::hbc::BCProviderBase&&, hermes::vm::RuntimeModuleFlags, llvh::StringRef, hermes::vm::Handlehermes::vm::Environment, hermes::vm::Handlehermes::vm::HermesValue) + 1204
22 hermes 0x104dd6904 facebook::hermes::HermesRuntimeImpl::evaluatePreparedJavaScript(std::__1::shared_ptr<facebook::jsi::PreparedJavaScript const> const&) + 224
23 hermes 0x104dd679c facebook::hermes::HermesRuntime::evaluateJavaScriptWithSourceMap(std::__1::shared_ptr<facebook::jsi::Buffer const> const&, std::__1::shared_ptr<facebook::jsi::Buffer const> const&, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator> const&) + 88
24 hermes 0x104dd76dc facebook::hermes::HermesRuntimeImpl::evaluateJavaScript(std::__1::shared_ptr<facebook::jsi::Buffer const> const&, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator> const&) + 32
25 APPX_MOBILE 0x103d8ed54 0x102870000 + 22146388
26 APPX_MOBILE 0x103cb0cf0 0x102870000 + 21236976
27 APPX_MOBILE 0x1039d006c 0x102870000 + 18219116
28 APPX_MOBILE 0x1039d1044 0x102870000 + 18223172
29 APPX_MOBILE 0x103736628 0x102870000 + 15492648
30 APPX_MOBILE 0x10374265c 0x102870000 + 15541852
31 APPX_MOBILE 0x103742468 0x102870000 + 15541352
32 CoreFoundation 0x189aeb444 CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 28
33 CoreFoundation 0x189ad9658 __CFRunLoopDoBlocks + 356
34 CoreFoundation 0x189ad933c __CFRunLoopRun + 2432
35 CoreFoundation 0x189ad85b8 CFRunLoopRunSpecific + 572
36 APPX_MOBILE 0x10372be50 0x102870000 + 15449680
37 Foundation 0x188780158 NSThread__start + 724
38 libsystem_pthread.dylib 0x210e5937c _pthread_start + 136
39 libsystem_pthread.dylib 0x210e54494 thread_start + 8
The kernel sends SIGKILL to application if it handles ES_EVENT_TYPE_AUTH_OPEN and lldb is attached to this process.
App:
int main(int /*argc*/, char** /*argv*/)
{
es_client_t *pEpClient = nullptr;
es_new_client_result_t result = es_new_client(&pEpClient, ^(es_client_t *pClient, const es_message_t *pMessage)
{
switch (pMessage->event_type)
{
case ES_EVENT_TYPE_AUTH_OPEN:
{
uint32_t authorizedFlags = pMessage->event.open.fflag;
if ((authorizedFlags & FREAD) || (authorizedFlags & FWRITE))
{
std::filesystem::path filePath = std::string(pMessage->event.open.file->path.data, pMessage->event.open.file->path.length);
std::string fileName = filePath.filename();
if (fileName == "test.txt")
{
std::cout << "blocked fileName: " << filePath.filename() << std::endl;
authorizedFlags &= ~FWRITE;
authorizedFlags &= ~FREAD;
}
}
if (es_respond_flags_result(pClient, pMessage, authorizedFlags, false) != ES_RESPOND_RESULT_SUCCESS)
{
std::cout << "es_respond_flags_result() failed with error " << std::endl;
}
}
break;
default:
break;
}
});
if (result != ES_NEW_CLIENT_RESULT_SUCCESS)
{
std::cout << "es_new_client() failed." << std::endl;
return 1;
}
es_event_type_t eventsList[] =
{
ES_EVENT_TYPE_AUTH_OPEN
};
if (es_subscribe(pEpClient, eventsList, 1) == ES_RETURN_ERROR)
{
std::cout << "es_subscribe() failed." << std::endl;
}
// wait
int i = 0;
std::cin >> i;
if (es_delete_client(pEpClient) == ES_RETURN_ERROR)
{
std::cout << "es_delete_client() failed." << std::endl;
}
return 0;
}
(lldb) process attach --pid 61127
....
(lldb) c
Process 61127 resuming
Process 61127 exited with status = 9 (0x00000009) Terminated due to signal 9
System log:
Allowing set_exception_ports from [debugserver] on [ep_sample] for entitled process/debugger
Client did not respond in appropriate amount of time (client pid: 61127), sent SIGKILL
Delete the Documents path of the app
Will the files or folders in the documentDirectory path or applicationSupportDirectory path disappear or be deleted when the OS is updated?
I know that sometimes all the files in the cachesDirectory path are deleted when the OS is updated or the device is rebooted.
Sometimes, users of my app report that all the files in the documentDirectory path or applicationSupportDirectory path are deleted or disappear, or all the files are deleted and initialized.
I thought that the files or folders in the documentDirectory path or applicationSupportDirectory path were not affected by the OS update, but am I wrong?
After installing the app with distribution certificate, iPhone is getting very slow in some random devices with iOS version 18.0.1 where as the same app installed through TestFlight & AppStore is working fine . Could you please provide your support to diagnose this issue?
Devices with iOS 18.0.1 which are showing issues:-
iPhone XR, iPhone 16 pro.
Thanks.
It seems that the connection failure occurs when attempting to establish GATT connections with 9 BLE devices simultaneously.
However, when connecting fewer than 8 or more than 10 devices, data can be received without issues.
Upon investigation, the following points have been identified:
This issue does not occur on iPad 10th generation.
The iPad 9th generation uses Bluetooth 4.2, while the iPad 10th generation uses Bluetooth 5.0, so this difference might be the cause.
The limitation is 9 devices per device, not per App.
The issue occurs even when trying to connect 8 BLE devices with App 1 and 1 BLE device with App 2.
It appears that the 9th device experiencing the connection failure is not receiving the result of the service discovery.
According to the PacketLogger logs, the connection itself is established, but the service discovery results are not returned.
When a 10th device is connected, the 9th device also connects successfully.
Once the 10th device connects, the service discovery results for the 9th device are returned.
The reproduction steps are as follows:
Device:
iPad 9th generation (iPadOS 17.6.1)
Procedure:
Prepare 9 BLE devices.
Connect each BLE device to the iPad one by one.
Data can be received from devices 1 through 8, but data cannot be received from the 9th device.
We hook the memory related APIs with ourselves' functions, like below:
if ((malloc_get_all_zones(0, nullptr, reinterpret_cast<vm_address_t**>(&allZones), &numZones) == KERN_SUCCESS) && (numZones > 0) && (numZones > 0))
{
if (allZones[0] == nullptr )
{
return false;
}
trackZone = allZones[0]
trackZone->malloc = &my_malloc;
trackZone->calloc = &my_calloc;
trackZone->valloc = &my_valloc;
trackZone->memalign = &my_memalign;
trackZone->free = &my_free;
trackZone->free_definite_size = &my_free_definite_size;
trackZone->try_free_default = &my_try_free_default;
trackZone->realloc = &scf_realloc;
}
our functions are called when allocate memory with XCode15+MacOS14.6, but when we upgrade the compiling env to XCode16+MacOS15, it won't work any more.
For a personal project, I have been writing some library to interface the CoreBluetooth API with the go language. Because of what it does, that library is written in objective-C with ARC disabled.
One function I had to write takes a memory buffer (allocated with malloc() on the go side), creates an NSData object out of it to pass the data to the writeValue:forCharacteristic:type: CoreBluetooth method, and then releases the NSData as well as the original memory buffer:
void Write(CBPeripheral *p, CBCharacteristic *c, void *bytes, int len) {
NSData *data = [NSData dataWithBytesNoCopy:bytes length:len freeWhenDone:true];
[p writeValue:data forCharacteristic:c type:CBCharacteristicWriteWithoutResponse];
[data release];
}
One thing I noticed is that the retainCount for data increases during the writeValue:forCharacteristic:type: API call. It is 1 before, and 2 after. This is surprising to me, because the documentation says "This method copies the data passed into the data parameter, and you can dispose of it after the method returns."
I suspects this results in a memory leak. Am I missing something here ?
Hi all:
I am experimenting with Finder extensions. I’d like to be able to add a context menu to all folder locations. I believe the code below should work, but it doesn’t. If I hard code a path, it does work. Any tips on what I am missing?
Thanks!
// Doesn’t work
FIFinderSyncController.default().directoryURLs = nil
// Works for user folder
var myFolderURL = URL(fileURLWithPath: "/users/exampleuser")
FIFinderSyncController.default().directoryURLs = [self.myFolderURL]
Hi, I am trying to write simple code that my iPhone acts as BLE peripheral (advertise packet). but i cannot see the advertisement on other devices that do scanning. What could be the cause?
Code snippet
=============
import SwiftUI
import CoreBluetooth
// 1. Conform to CBPeripheralManagerDelegate
class BLEAdvertiser: NSObject, ObservableObject, CBPeripheralManagerDelegate {
var peripheralManager: CBPeripheralManager?
// 2. Start advertising
func startAdvertising() {
peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
}
// 3. CBPeripheralManagerDelegate method called when state changes
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
switch peripheral.state {
case .poweredOn:
// Define a service UUID
let serviceUUID = CBUUID(string: "1234") // Custom UUID for your service
// Create a CBMutableService
let service = CBMutableService(type: serviceUUID, primary: true)
// Add service to the peripheral manager
peripheralManager?.add(service)
// Start advertising the service
let advertisementData: [String: Any] = [
CBAdvertisementDataServiceUUIDsKey: [serviceUUID],
CBAdvertisementDataLocalNameKey: "My iPhone"
]
peripheralManager?.startAdvertising(advertisementData)
print("Started advertising!")
case .poweredOff:
print("Bluetooth is powered off.")
case .resetting:
print("Bluetooth is resetting.")
case .unauthorized:
print("Bluetooth access is unauthorized.")
case .unsupported:
print("Bluetooth is unsupported on this device.")
case .unknown:
print("Bluetooth state is unknown.")
@unknown default:
print("A new state that we don’t know about.")
}
}
// 4. Optional: Handle peripheral manager adding service
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
if let error = error {
print("Failed to add service: \(error.localizedDescription)")
return
}
print("Service added successfully!")
}
}
struct ContentView: View {
@StateObject private var bleAdvertiser = BLEAdvertiser()
var body: some View {
VStack {
Text("BLE Advertising")
.font(.largeTitle)
.padding()
Button(action: {
bleAdvertiser.startAdvertising()
}) {
Text("Start Advertising")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
}
}
}