Hello,
I wrote a simple email validation test:
struct ContentView: View {
@State private var email: String
@State var emailIsValid: Bool = true
public init(email: String = "")
{
self.email = email
}
var body: some View {
Text("Hello, world!")
.padding()
TextField("Email", text: $email)
.onChange(of: email) { newValue in
if(newValue.range(of:"^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", options: .regularExpression) != nil) {
self.emailIsValid = true
print("valid")
} else {
self.emailIsValid = false
print("invalid")
}
}
.foregroundColor(emailIsValid ? Color.green : Color.red)
}
}
And it works for the email like Test@gmail.com. Text is green.
But if I type something like Testerka@gmail.com text stays red. But the print output says 'valid'.
Post
Replies
Boosts
Views
Activity
Hi,
Xcode warns me that NSPersistentContainer, NSManagedObjectContext, NSPersistentHistoryTransaction and NSPersistentHistoryToken are non-Sendable types and therefore cannot cross actor boundaries.
These warnings occur even when I use @preconcurrency import CoreData (only works with Xcode 14.0 Beta, in Xcode 13.4.1, it says '@preconcurrency' attribute on module 'CoreData' is unused)
I understand that types in Core Data have yet to be marked as Sendable when it makes sense.
Although NSPersistentHistoryTransaction, and NSPersistentHistoryToken are reference types, they should qualify to be marked as Sendable in the future since these are immutable types, am I right?
NSPersistentContainer provides variables and methods like viewContext and newBackgroundContext(). It would make sense that this type is thread-safe. However, I'm not sure about it, especially regarding its loadPersistentStores(completionHandler:) method. Is NSPersistentContainer (and its subclass NSPersistentCloudKitContainer) thread-safe and should it be marked as Sendable in the future?
The case of and NSManagedObjectContext confuses me the most. Indeed, it has both thread-safe methods like perform(_:) and thread-unsafe methods like save(). Still, it should be possible to cross actor boundaries. Would such a "partially thread-safe" type quality to be marked as Sendable? If not, how can it cross actor boundaries?
The reason I'm asking these questions is that I have a CoreDataStack type.
It has mutable variables, such as var lastHistoryToken: NSPersistentHistoryToken?, needs to perform work without blocking the main thread, such as writing the token to a file, has async methods, uses notification observers, and needs to be marked as Sendable to be used by other controllers running on different actors.
Since this type is related to back-end work, I made it an Actor. This type exposes the persistent container, and a method to create new background threads.
However, I need to explicitly annotate all methods using await context.perform { ... } as nonisolated in this actor. Not doing so causes a data race to be detected at runtime. Is this a bug, and is making a Core Data stack an Actor the proper way to do it or is there a better solution?
Any help would be greatly appreciated.
Thanks.
Xcode Configuration
Xcode 13.4.1, Xcode 14.0 beta 5
The Xcode project is configured with Other Swift Flags set to -Xfrontend -warn-concurrency -Xfrontend -enable-actor-data-race-checks.
Hi,
It seems that there's a bug in the iOS and iPadOS 16 betas (i've not test in macOS 13 yet), that when after updating a List data source with a bigger array, scrolling to a row of an offset bigger than the previous data array, with ScrollViewProxy, will crash the app with an EXC_BREAKPOINT (code=1, subcode=0x1099d6004) error.
Below I attached a sample code to reproduce the crash. In it when opening there's an empty list. When pressing the "Randomize & Select Last" button at the top, the list will be filled with 5 random UUIDs, followed by scrolling to the last row. The app will crash on the second try, when it will try to scroll to an offset bigger than the previous data array (the last row).
As a control there's an "Randomize & Select Random" button that will behave more or less like the "Randomize & Select Last" button but will choose a random row to select and scroll. It will only crash if this select row if of an offset bigger that the size of the previous array.
This doesn't happen in iOS 15.
I've already posted the Radar as FB11302966, however if someone has any toughs on how to solve this problem (or what I'm doing wrong) they are welcome.
Sample code:
///A simple data model for the demo. Only stores an UUID.
struct DataModel: Identifiable, Hashable {
let id: UUID = UUID()
var nameUUID: String {
id.uuidString
}
}
struct ContentView: View {
///Array with some data to show
@State private var data: [DataModel] = []
///Selected row
@State private var selection: DataModel?
var body: some View {
VStack(alignment: .leading) {
HStack {
//Create a new array for showing in the list.
//This array will be bigger than the last one.
//The selection will be the last element of the array (triggering the bug)
Button {
//Increment the size of the new List by 5
let numberElements = data.count + 5
//Create a new Array of DataModel with more 5 elements that the previous one
let newData = (0 ..< numberElements).map { _ in DataModel() }
//Select the last element of the array/list.
//This will make sure that the scrollTo will go to the end
let newSelection = newData.last
//Update STate for the new values
data = newData
selection = newSelection
} label: {
Text("Randomize & Select Last")
}
Spacer()
//Create a new array for showing in the list.
//This array will be bigger than the last one.
//The selection will be the a random element of the array (only triggering the bug when the element is )
Button {
//Increment the size of the new List by 5
//If empty will start with 40 (reducing the odds of triggering the bug)
let numberElements = data.count == 0 ? 40 : data.count + 5
//Create a new Array of DataModel with more 5 elements that the previous one
let newData = (0 ..< numberElements).map { _ in DataModel() }
//Select a random element of the array/list.
//This will scroll if the element is 'inside' the previous list
//Otherwise will crash
let newSelection = newData.randomElement()
//Update State for the new values
data = newData
selection = newSelection
} label: {
Text("Randomize & Select Random")
}
}
.padding()
//MARK: ScrollViewReader and List
ScrollViewReader {
proxy in
List(data, selection: $selection) {
dataElement in
//Row (is only the UUID for the rows
Text(dataElement.id.uuidString)
.id(dataElement)
.tag(dataElement)
}
//action that fires when data changes
//it will scroll to the selection
.onChange(of: data, perform: { newValue in
if let selection {
proxy.scrollTo(selection)
}
})
}
}
}
}
Hola, tengo un problema con una app enterprise el cual me arroja un mensaje cuando termina de instalarse (No se pudo instalar "My-App" intente mas tarde), solo es con iOS 16 BETA, si el ipa se instala desde xcode no existe ningun problema, solo es cuando se distribuye mendiante storage de Google, Alguien le sucede algo similar ?
Hi all,
I am trying to use the new CarPlay Simulator (the one provided with the Xcode Additional Tools) to test an application that uses a protocol string. My question is: is there a way to edit this protocol string on this application? Because as of right now, my app is not shown in the CarPlay Simulator, as it does not have the required protocol string.
I've used the Xcode simulator, and protocol strings can be added using:
defaults write com.apple.iphonesimulator CarPlayProtocols -array-add <protocol-string>
But I've not found a way to do this on the standalone application.
Thank you all in advance
I'm testing network loss handling in my app on the simulator.
Turning WiFi OFF triggers pathUpdateHandler with .unsatisfied status.
Turning WiFi back to ON triggers pathUpdateHandler with .unsatisfied status again.
I noticed that pathUpdateHandler is triggered right after I enabled WiFi, but before WiFi actually connects to the network. When the laptop is actually connected to the WiFi network - pathUpdateHandler isn't triggered, so my app stays in "offline" mode permanently.
networkMonitor.pathUpdateHandler = { [weak self] path in
guard let self = self else { return }
DispatchQueue.main.async {
if path.status == .satisfied {
self.status = .connected
} else {
print(path.unsatisfiedReason)
self.status = .disconnected
}
}
}
monitor.start(queue: queue)
networkMonitor is retained by my DIContainer
Hi
Can anyone help me out with this extra white space showing in dynamic island iPhones?
Any help is much appreciated.
Thanks.
Recently I updated to Xcode 14.0. I am building an iOS app to convert recorded audio into text. I got an exception while testing the application from the simulator(iOS 16.0).
[SpeechFramework] -[SFSpeechRecognitionTask handleSpeechRecognitionDidFailWithError:]_block_invoke Ignoring subsequent recongition error: Error Domain=kAFAssistantErrorDomain Code=1101 "(null)"
Error Domain=kAFAssistantErrorDomain Code=1107 "(null)"
I have to know what does the error code means and why this error occurred.
Hi,
do you know if it's possible to handle the flashlight inside DataScannerViewController?
I tried with AVCaptureDevice.DiscoverySession, but clearly when torchmode is on DataScannerViewController freeze...
Thanks
Luca
Hi,
I am working on an iPad application that has both Portrait and Landscape orientation. The issue that I am facing is regarding the the popup presentation that iPad shows you for saving password while you log-in in the application.
Now, when the pop-up is presented, at that moment if I try to rotate the device, the application crashes with the message
Application tried to present modally a view controller <_SFAppPasswordSavingViewController: 0x107be7230> that is already being presented by <UIKeyboardHiddenViewController_Save: 0x107a49190>.
Now, the problem is that SFAppPasswordSavingViewController presentation is not controlled by me. Also UIKeyboardHiddenViewController_Save,is something I am not controlling.
Please help me out on how to solve this issue or let me know if I am missing anything.
Hi,
We assume that when uninstalling an application, the UserDefaults are deleted.
Starting iOS16 we encounter complaints from clients that this is not the case. We have succeeded in debugging a device where this occurred (UserDefaults were not deleted after uninstall+install), but have not succeeded in recreating this issue on another device.
We assume this issue has a connection to iCloud sync, although UserDefaults iCloud synching should be specifically set up (using NSUbiquitousKeyValueStore) which we have NOT set. Or maybe it has to do with Family Sharing.
We are initializing the UserDefaults with suiteName for usage in widgets, but assume this has not connection to the bug.
So far I'm unable to use Regex literals in my Swift Packages. Xcode simply gives a syntax error and has no idea I'm trying to do Regex.
This is with Xcode 14.1 and all the platforms in the Package.swift have been set to the minimum requirement (iOS 16, macOS 13, etc) as well as the swift-tools-version set to 5.7. Using the Regex type directly (try Regex("[a-z]")) does work. It's just the literals that Xcode refuses to recognize.
Regex literals do work in app projects and playgrounds.
Is there a setting in the Package.swift or something I'm forgetting?
Thanks in advance!
I am trying to save an image to the user's photo library using PHPhotoLibrary and set the image file name at the time of saving suing the code below. This is working the first time, but if I then try to save the same image again with a different file name, it saves with the same file name as before.
Is there something I need to add to let the system know to save a new version of the image with a new file name?
Thank you
PHPhotoLibrary.shared().performChanges ({
let assetType:PHAssetResourceType = .photo
let request:PHAssetCreationRequest = .forAsset()
let createOptions:PHAssetResourceCreationOptions = PHAssetResourceCreationOptions()
createOptions.originalFilename = "\(fileName)"
request.addResource(with: assetType, data: image.jpegData(compressionQuality: 1)!, options: createOptions)
}, completionHandler: { success, error in
if success == true && error == nil {
print("Success saving image")
} else {
print("Error saving image: \(error!.localizedDescription)")
}
})
I have to pair the classic Bluetooth device with my iOS application. For that, I have implemented showBluetoothAccessoryPicker with the External Accessory framework.
EAAccessoryManager.shared().showBluetoothAccessoryPicker(withNameFilter: nil)), this is the code I have used for that. Added "Supported external accessory protocols" in .plist and enabled Wireless Accessory Configuration from capabilities.
The actual issue is the picker displaying the device to pair with a 1-minute delay. What is the reason behind this reason and how can we resolve that?
I tried to use swift to solve an algorithm problem, but it gave me an error
Problem Link: https://leetcode.com/problems/number-of-matching-subsequences/
class Solution {
func bisect_right(arr: [Int], num: Int) -> Int {
var l = 0, r = arr.count - 1
while l < r {
var m = (l+r) / 2
if arr[m] <= num {
l = m + 1
} else {
r = m
}
}
return l
}
func numMatchingSubseq(_ s: String, _ words: [String]) -> Int {
var pos: [Character: [Int]] = [:]
for (i, c) in s.enumerated() {
pos[c]!.append(i)
}
var cnt = 0
for word in words {
var prev = -1, ok = true
for c in word {
let ps = pos[c]!
var res = bisect_right(arr: ps, num: prev)
if res == ps.count {
ok = false; break
}
prev = ps[res]
}
if ok {
cnt += 1
}
}
return cnt
}
}
i.e.
s= "abcde"
words = ["a","bb","acd","ace"]
Can anyone help to understand what is causing this warning message on this SampleCode.
it happens when data in table gets updated
it happens when I have lot of items in table and search for lets say # 6543 and then clear the search.
"WARNING: Application performed a reentrant operation in its NSTableView delegate. This warning will become an assert in the future."
If there are just few items in table, the warning is not there.
And it started when updated to Xcode Version 14 and upward
import SwiftUI
import Foundation
@main
struct TestProjectSWIFTApp: App {
@StateObject var mydata: MyData = MyData()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(mydata)
}
}
}
struct ContentView: View {
@EnvironmentObject var mydata: MyData
var body: some View {
NavigationView{
NavigationLink("TABLE", destination: MyTable())
}
}
}
struct User: Identifiable {
let id: UUID = UUID()
var name: String
var score: Int
}
struct MyTable: View {
@EnvironmentObject var mydata: MyData
@State private var sortOrder = [KeyPathComparator(\User.name)]
@State var searchText: String = ""
var searchResults : [User] {
if searchText.isEmpty {
return mydata.alldata
} else {
return mydata.alldata.filter{$0.name.localizedCaseInsensitiveContains(searchText)}
}
}
var body: some View {
Button("Generate new data", action: {
mydata.updateTable()
})
Table(searchResults, sortOrder: $sortOrder) {
TableColumn("Score"){
Text("\(Double($0.score))")
}
TableColumn("user", value: \.name)
}
.onChange(of: sortOrder) {
mydata.alldata.sort(using: $0)
}
.searchable(text: $searchText)
}
}
@MainActor class MyData : ObservableObject{
@Published var alldata: [User] = []
init(){
self.setData()
}
func setData(){
alldata = [
User(name: "User 1", score: 95),
User(name: "User 2", score: 80),
User(name: "User 3", score: 85)
]
}
func updateTable(){
var newallData: [User] = []
var x = 0
while x < 10000{
newallData.append(User(name: "User #\(x)", score: Int.random(in: 10..<999999)))
x = x + 1
}
alldata = newallData
}
}
We implemented communication between Swift App and DriverKit driver using IOConnectCallAsyncStructMethod.
void USBDriverClass::registerAsyncCallback(){
// Async required variables
notificationPort = NULL;
machNotificationPort = NULL;
runLoopSource = NULL;
// Async initialization
globalRunLoop = CFRunLoopGetMain();
CFRetain(globalRunLoop);
notificationPort = IONotificationPortCreate(kIOMainPortDefault);
if (notificationPort == NULL)
{
printf("Failed to create notification port for application.\n");
}
machNotificationPort = IONotificationPortGetMachPort(notificationPort);
if (machNotificationPort == 0)
{
printf("Failed to get mach notification port for application.\n");
}
runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
if (runLoopSource == NULL)
{
printf("Failed to get run loop for application.\n");
}
// Establish our notifications in the run loop, so we can get callbacks.
CFRunLoopAddSource(globalRunLoop, runLoopSource, kCFRunLoopDefaultMode);
// Establish our "AsyncCallback" function as the function that will be called by our Dext when it calls its "AsyncCompletion" function.
// We'll use kIOAsyncCalloutFuncIndex and kIOAsyncCalloutRefconIndex to define the parameters for our async callback
// This is your callback function. Check the definition for more details.
asyncRef[kIOAsyncCalloutFuncIndex] = (io_user_reference_t)AsyncCallback;
// Use this for context on the return. For example you might pass "this". But since this example is entirely static, we'll skip that step.
asyncRef[kIOAsyncCalloutRefconIndex] = (io_user_reference_t)NULL;
kern_return_t ret = kIOReturnSuccess;
uint8_t words = 4;
size_t inputSize = sizeof(StructA);
StructA structA;
structA.tag = 1;
structA.length = 0;
structA.values[0] = 0x106000;
structA.values[1] = words * sizeof(uint32_t);
size_t outputSize = sizeof(OutputData);
OutputData data;
printf("registerAsyncCallback called");
ret = IOConnectCallAsyncStructMethod(connection, MessageType_RegisterAsyncCallback, machNotificationPort, asyncRef, kIOAsyncCalloutCount, &structA, inputSize, &data, &outputSize);
if (ret != kIOReturnSuccess)
{
printf("IOConnectCallAsyncStructMethod failed with error: 0x%08x.\n", ret);
}
}
And when we get data from device we send data back from Driver to Swift app
ivars->mUSBProbeDriverClient->AsyncCompletion(ivars->streamingDataCallback, kIOReturnSuccess, asyncData, 16);
Driver should transfer data to swift app asynchronously when it's provided by USB device so we can not transfer struct synchronously.
Async call back has limitation of 16 of uint64_t only and our application require larger data transfer.
The logical way to transfer data using a memory buffer and as per Apple documentation they are providing this using IODataQueueDispatchSource. But they have not provided any example or showed how to use this.
How to use fill buffer and use it in swift app using IODataQueueDispatchSource?
Hi,
When using VNFeaturePrintObservation and then computing the distance using two images, the values that it returns varies heavily. When two identical images (same image file) is inputted into function (below) that I have used to compare the images, the distance does not return 0 while it is expected to, since they are identical images.
Also, what is the upper limit of computeDistance? I am trying to find the percentage similarity between the two images. (Of course, this cannot be done unless the issue above is resolved).
Code that I have used is below
func featureprintObservationForImage(image: UIImage) -> VNFeaturePrintObservation? {
let requestHandler = VNImageRequestHandler(cgImage: image.cgImage!, options: [:])
let request = VNGenerateImageFeaturePrintRequest()
request.usesCPUOnly = true // Simulator Testing
do {
try requestHandler.perform([request])
return request.results?.first as? VNFeaturePrintObservation
} catch {
print("Vision Error: \(error)")
return nil
}
}
func compare(origImg: UIImage, drawnImg: UIImage) -> Float? {
let oImgObservation = featureprintObservationForImage(image: origImg)
let dImgObservation = featureprintObservationForImage(image: drawnImg)
if let oImgObservation = oImgObservation {
if let dImgObservation = dImgObservation {
var distance: Float = -1
do {
try oImgObservation.computeDistance(&distance, to: dImgObservation)
} catch {
fatalError("Failed to Compute Distance")
}
if distance == -1 {
return nil
} else {
return distance
}
} else {
print("Drawn Image Observation found Nil")
}
} else {
print("Original Image Observation found Nil")
}
return nil
}
Thanks for all the help!
I've followed along with the Screen Time API demos (https://developer.apple.com/videos/play/wwdc2021/10123/)
Also followed along with this guide, which is essentially the same:
https://www.folio3.com/mobile/blog/screentime-api-ios/
I'm able to restrict access to apps/categories with the FamilyActivityPicker and FamilyActivitySelection.
I can set a DeviceActivitySchedule, and then use DeviceActivityCenter to start monitoring it.
I can tell that the schedule is working, because MyMonitor:intervalDidStart() does get called, and it works except for the restricting of apps/categories/webCategories.
It's as if MyModel does not have any values set from within MyMonitor. I've confirmed that MyModel does have the correct FamilyActivitySelection apps etc, everywhere else in my Target, before and after the MyMonitor:intervalDidStart() gets called.
MyMonitor is in a separate target called MonitorExtension, that I created using the Device Activity Monitor Extension template. But I made sure to set the Target Membership of MyModel to both my main target, and my extension target.
I have set NSExtensionPrincipalClass to $(PRODUCT_MODULE_NAME).MyMonitor, as suggested.
I have added MyModel.swift to the Compiled Sources in my extensions Build Phases.
I have edited my apps build scheme, to make sure the extension target is also built.
One more interesting thing is that debugger breakpoints and print statements do not work from within my extension. I've even tried caching a string from within MyMonitor:intervalDidStart, and tried to retrieve it afterwards in my main target, but it is nil.
Still, I've confirmed that intervalDidStart was actually called by adding any removing store.application.denyAppInstallation = true, and having it work correctly.
I've spent so much time on this problem, any help would be massive..
Here are the files I've referenced:
import UIKit
import MobileCoreServices
import ManagedSettings
import DeviceActivity
class MyMonitor: DeviceActivityMonitor {
let store = ManagedSettingsStore()
override func intervalDidStart(for activity: DeviceActivityName) {
super.intervalDidStart(for: activity)
let model = MyModel.shared
let applications = model.selectionToDiscourage.applicationTokens
let categories = model.selectionToDiscourage.categoryTokens
let webCategories = model.selectionToDiscourage.webDomainTokens
if applications.isEmpty {
print("No applications to restrict")
} else {
store.shield.applications = applications
}
if categories.isEmpty {
print("No categories to restrict")
} else {
store.shield.applicationCategories = ShieldSettings.ActivityCategoryPolicy.specific(categories, except: Set())
}
if webCategories.isEmpty {
print("No web categories to restrict")
} else {
store.shield.webDomains = webCategories
}
store.dateAndTime.requireAutomaticDateAndTime = true
store.account.lockAccounts = true
store.passcode.lockPasscode = true
store.siri.denySiri = true
store.appStore.denyInAppPurchases = true
store.appStore.maximumRating = 200
store.appStore.requirePasswordForPurchases = true
store.media.denyExplicitContent = true
store.gameCenter.denyMultiplayerGaming = true
store.media.denyMusicService = true
store.application.denyAppInstallation = true
}
override func intervalDidEnd(for activity: DeviceActivityName) {
super.intervalDidEnd(for: activity)
store.shield.applications = nil
store.shield.applicationCategories = nil
store.shield.webDomains = nil
store.dateAndTime.requireAutomaticDateAndTime = false
store.account.lockAccounts = false
store.passcode.lockPasscode = false
store.siri.denySiri = false
store.appStore.denyInAppPurchases = false
store.appStore.maximumRating = 1000
store.appStore.requirePasswordForPurchases = false
store.media.denyExplicitContent = false
store.gameCenter.denyMultiplayerGaming = false
store.media.denyMusicService = false
store.application.denyAppInstallation = false
}
}
import Foundation
import FamilyControls
import DeviceActivity
import ManagedSettings
class MyModel: ObservableObject {
static let shared = MyModel()
let store = ManagedSettingsStore()
private init() {}
var selectionToDiscourage = FamilyActivitySelection() {
willSet {
let applications = newValue.applicationTokens
let categories = newValue.categoryTokens
let webCategories = newValue.webDomainTokens
store.shield.applications = applications.isEmpty ? nil : applications
store.shield.applicationCategories = ShieldSettings.ActivityCategoryPolicy.specific(categories, except: Set())
store.shield.webDomains = webCategories
}
}
func initiateMonitoring(scheduleStart: DateComponents, scheduleEnd: DateComponents) {
let schedule = DeviceActivitySchedule(intervalStart: scheduleStart, intervalEnd: scheduleEnd, repeats: true, warningTime: nil)
print(scheduleStart)
print(scheduleEnd)
let center = DeviceActivityCenter()
do {
try center.startMonitoring(.daily, during: schedule)
}
catch {
print ("Could not start monitoring \(error)")
}
store.dateAndTime.requireAutomaticDateAndTime = false
store.account.lockAccounts = false
store.passcode.lockPasscode = false
store.siri.denySiri = false
store.appStore.denyInAppPurchases = false
store.appStore.maximumRating = 1000
store.appStore.requirePasswordForPurchases = false
store.media.denyExplicitContent = false
store.gameCenter.denyMultiplayerGaming = false
store.media.denyMusicService = false
store.application.denyAppInstallation = false
}
}
extension DeviceActivityName {
static let daily = Self("daily")
}
import SwiftUI
import FamilyControls
struct AppPicker: View {
@StateObject var model = MyModel.shared
@State var isPresented = false
var body: some View {
Button("Select Apps to Discourage") {
isPresented = true
}
.familyActivityPicker(isPresented: $isPresented, selection: $model.selectionToDiscourage)
}
}
I'm trying to change app icon on Dock in macOS from my app. But couldn't get to work. The setAlternateIconName works fine in iOS simulator, but when I run in on my mac (Catalyst) I got this error: The requested operation couldn’t be completed because the feature is not supported.
Apple Doc - https://developer.apple.com/documentation/uikit/uiapplication/2806818-setalternateiconname
Thank you