How can I use the Network framework to establish a "client-server" type relationship between a server iPad and, say, 3 client iPads?
I've downloaded the TicTacToe sample app,
https://developer.apple.com/documentation/network/building_a_custom_peer-to-peer_protocol
which demonstrates nicely a connection between a PeerListener and a PeerBrowser.
However, I then tried to make an array of PeerConnection objects rather than a single one, and send data to each one separately from the PeerListener. However, what appears to happen is that the 1st PeerBrowser connects successfully, but when the 2nd PeerBrowser connects, it replaces the 1st PeerBrowser, and both PeerConnection objects in the array point to the 2nd PeerBrowser, so when I send data via either PeerConnection, the data arrives at the 2nd PeerBrowser.
Is it possible to do this? If so, how can I establish multiple PeerConnections between 1 "server" iPad and multiple "client" iPads?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
As Natascha notes in her helpful article
https://tanaschita.com/20230807-migrating-to-observation/
pre-iOS17 was like this,
Stateview Subview
-----------------------------------------
Value Type @State @Binding
Ref Type @StateObject @ObservedObject
With iOS 17, it's like this:
Stateview Subview
-----------------------------------------
Value Type @State @Binding
Ref Type @State @Bindable
I like how they simplified @State and @StateObject into just @State for both cases. I'm curious, though, why didn't they simplify @Binding and @ObservedObject into just @Binding? Why did they need to maintain the separate property wrapper @Bindable? I'm sure there's a good reason, just wondering if anybody knew why.
Interestingly, you can use both @Binding and @Bindable, and they both seem to work. I know that you're supposed to use @Bindable here, but curious why @Binding works also.
import SwiftUI
@Observable
class TestClass {
var myNum: Int = 0
}
struct ContentView: View {
@State var testClass1 = TestClass()
@State var testClass2 = TestClass()
var body: some View {
VStack {
Text("testClass1: \(testClass1.myNum)")
Text("testClass2: \(testClass2.myNum)")
// Note the passing of testClass2 without $. Xcode complains otherwise.
ButtonView(testClass1: $testClass1, testClass2: testClass2)
}
.padding()
}
}
struct ButtonView: View {
@Binding var testClass1:TestClass
@Bindable var testClass2:TestClass
var body: some View {
Button(action: {
testClass1.myNum += 1
testClass2.myNum += 2
} , label: {
Text("Increment me")
})
}
}
Our app runs a background task while it's locked that calls a web service, and presents a URLCredential with a SecIdentity. It works fine if you simulate the background task using,
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.ourapp.extendedtask"]
but when it actually runs in the background with the device locked, and I try to fetch the SecIdentity from the Keychain using SecItemCopyMatching, it fails with
-25308 (errSecInteractionNotAllowed)
I tried adding kSecAttrAccessibleAfterFirstUnlock when writing to the Keychain like this,
let keychainAddQuery: [String: Any] = [
kSecValueRef as String: identity,
kSecAttrLabel as String: "certKey",
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
]
let addResult = SecItemAdd(keychainAddQuery as CFDictionary, nil)
But it still fails when the background task tries to fetch it from the Keychain using SecItemCopyMatching. I could try using
kSecAttrAccessibleAlways
when I write to the Keychain, but the documentation says that is deprecated.
Is there a way to write the SecIdentity to a file and storing that within the Application Support folder rather than in the Keychain? So it's accessible when the BackgroundTask runs while the device is locked?
Our original approach was to put the PFX file in the Application Support folder, and store the password in the Keychain, then use SecPKCS12Import to generate the SecIdentity. However, it never gets that far, because fetching the password with SecItemCopyMatching didn't work due to the errSecInteractionNotAllowed issue. I then tried writing the SecIdentity itself to the Keychain using SecItemAdd as shown above, but encountered the same problem when the Background Task tried to fetch it using SecItemCopyMatching. I realize now it's not an issue with the specifics of the data being fetched from the Keychain, but rather a security issue reading from the Keychain while in the background.