Posts

Post marked as solved
2 Replies
@Polyphonic Solved this for me but the example they posted did not work for me in the xcode playground I had to prove it. In order to call dismissSearch from a parent view's .onSubmit(of: .search) one must find a way to store the reference to the child view's dismissSearch environment value in a way that the parent can call it. For example, use a ViewModel of some kind to store a function that you can overwrite from the child with the child's dismissSearch environment value when it becomes available in an onAppear or something similar. class ViewModel { var dismissClosure: () -> Void = { print("Not Set") } } Pass this ViewModel to the child and then store the dismissSearch in the child so the parent can call it from the shared ViewModel .onAppear { viewModel.dismissClosure = { dismissSearch() } } Here is the complete solution to the posted problem. import SwiftUI import PlaygroundSupport class ViewModel { var dismissClosure: () -> Void = { print("Not Set") } } struct SearchingExample: View { @State var searchText = "" @State var didSubmit = false @Environment(\.dismissSearch) var dismissSearch let viewModel = ViewModel() var body: some View { NavigationStack { SearchedView(didSubmit: $didSubmit, viewModel: viewModel) .searchable(text: $searchText) .onSubmit(of: .search) { didSubmit = true viewModel.dismissClosure() } } } } struct SearchedView: View { @Environment(\.isSearching) var isSearching @Environment(\.dismissSearch) var dismissSearch @Binding var didSubmit: Bool let viewModel: ViewModel var body: some View { VStack { Text(isSearching ? "Searching!" : "Not searching.") Button(action: { dismissSearch() }, label: { Text("Dismiss Search") }) Button(action: { // Return Key for playground }, label: { Image(systemName: "paperplane") }) .frame(width: 30, height: 30) .keyboardShortcut(.defaultAction) if didSubmit { Text("You Submitted Search!") .onAppear { Task { @MainActor in try await Task.sleep(nanoseconds: 3_000_000_000) self.didSubmit = false } } } } .onAppear { viewModel.dismissClosure = { dismissSearch() } } } } PlaygroundPage.current.needsIndefiniteExecution = true PlaygroundPage.current.setLiveView(SearchingExample())
Post not yet marked as solved
2 Replies
This line of code was the issue somehow, but now it only saves grey videos(of correct length and size) to the photo library despite the video file being valid in the Files app on the physical iOS device.     vidWriter.startSession(atSourceTime: CMTimeMake(value: self.videoFrameCounter, timescale: self.videoFPS)) Even using the share/ UIActivityViewController provided by apple saved a grey video. oh well, just will link to the files app instead inside the app.
Post marked as solved
2 Replies
I was setting the frame duration in a funky way, changing it to this for 30fps made it work  self.frameDuration = CMTime(value: 1, timescale: 30)
Post marked as solved
2 Replies
Got rejected again. My provided App Review Information https://www.youtube.com/watch?v=hDjZirlId_Q requires Tello drone made by DJI, video demonstrates network capability and general app usage press connect, iOS app uses NetworkExtension framework to find drone's wifi network based on SSID prefix "TELLO-" when connected, iOS app sends message to drone to enter a command-able state when drone tells iOS app it can be commanded, command-able state, iOS app shows controller view drone starts sending video and status data, takes a moment to appear for user it's just a drone, it flys and does flips, nothing else. Response from app review team member We're looking forward to completing our review of your app. Before we can continue, we need a video that demonstrates the current version, 2.1, in use on a physical iOS device, pairing and interacting with the designated hardware. The demo video does not show a physical iOD device and the drone and how these interact and connect via Bluetooth. Keep these requirements in mind as you make your demo video: Only use footage of your app running on a physical iOS device, not on a simulator. Make sure the video clearly documents all relevant app features, services, and user permission requests. You can use a screen recorder to capture footage of your app in use. The app doesn’t use bluetooth. The demo video is recorded on a physical iOS device, the video is not recorded on a simulator. I clearly show how I use the WiFi and in my App Review notes I explain how I use wifi. This is made by Apple and is in included in the Apple NetworkExtension framework This is the second time I have been rejected for this despite following guidelines and requirements provided by the App Review team. This app was approved last year using the same exact video Here is a link from last year: https://www.youtube.com/watch?v=FwFQsfQwglY From this submission: https://www.youtube.com/watch?v=hDjZirlId_Q
Post not yet marked as solved
2 Replies
As said by the error and @OOPer you can't have StateObject in a non-view. It looks like RefactorAccounts is a StateObject for the second unnamed code block, the first view code block, what is it named? With that, please provide class/struct names in the future it's hard to understand what is happening without that, also hard to reference it in discussion. Make RefactorAccounts more like this: class RefactorAccounts: ObservableObject {         ///Takes object from @StateObject, presents as var     @Published var accountBackEnd = AccountBackEnd()     ///Calls to Class for published objects     @Published var publishedClasses = PublishedClassAccount() Also, add 3 slashes to the line(s) directly above a var/func/struct/class/enum/etc. declaration to add to the quick documentation that appears when you hover over code(also in the right hand side of xcode in the doc pane view) PublishedClassAccount, and AccountBackEnd will need to become ObservaleObjects themselves and use the @Published annotation on their own properties.
Post marked as solved
5 Replies
Thank you for your help! I'm able to record videos now but they appear as gray frames only. If you're able to point me in the right direction I would appreciate it. Here is the append function: 			// Record CMSampleBuffer with AVFoundation       if self.videoStreamManager.isRecording,         let videoPixelBuffer = self.videoStreamManager.videoWriterInputPixelBufferAdaptor {         if videoPixelBuffer.append(frame, withPresentationTime: CMTimeMake(value: self.videoStreamManager.videoFrameCounter, timescale: self.videoStreamManager.videoFPS)) {           self.videoStreamManager.videoFrameCounter += 1         } else {           print("Warning: Did not append video frame!")         }       }
Post marked as solved
5 Replies
I apologize for the extremely delayed response, this was for a side project that I am only now getting back onto and getting the same error. I had status 3(failed) and this is the output from the last function in the original post codeblack for the func endRecording() Full Error: Error Domain=AVFoundationErrorDomain Code=-11800 "Media format - sample description is unsupported for the specified format flavor" UserInfo={NSUnderlyingError=0x282636100 {Error Domain=NSOSStatusErrorDomain Code=-12717 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-12717), NSDebugDescription=Media format - sample description is unsupported for the specified format flavor, NSLocalizedDescription=The operation could not be completed}
Post marked as solved
9 Replies
Indeed, I was trying to use it in the same way as other frameworks where you loop on receiving to receive constant messages. I do believe I will need to do this for my two other UDP streams but now I have it working! Thanks!class UDPClient { var connection: NWConnection var address: NWEndpoint.Host var port: NWEndpoint.Port var resultHandler = NWConnection.SendCompletion.contentProcessed { NWError in guard NWError == nil else { print("ERROR! Error when data (Type: Data) sending. NWError: \n \(NWError!)") return } } init?(address newAddress: String, port newPort: Int32) { guard let codedAddress = IPv4Address(newAddress), let codedPort = NWEndpoint.Port(rawValue: NWEndpoint.Port.RawValue(newPort)) else { print("Failed to create connection address") return nil } address = .ipv4(codedAddress) port = codedPort connection = NWConnection(host: address, port: port, using: .udp) connection.stateUpdateHandler = { newState in switch (newState) { case .ready: print("State: Ready") case .setup: print("State: Setup") case .cancelled: print("State: Cancelled") case .preparing: print("State: Preparing") default: print("ERROR! State not defined!\n") } } connection.start(queue: .global()) } deinit { connection.cancel() } func sendAndReceive(_ data: Data) { self.connection.send(content: data, completion: self.resultHandler) self.connection.receiveMessage { data, context, isComplete, error in print("Receive isComplete: " + isComplete.description) guard let data = data else { print("Error: Received nil Data") return } print(String(data: data, encoding: .utf8)) } } }
Post marked as solved
9 Replies
In response to my listen method I treat the object making the connection like the connection itself. When I am done sending/receiving messages the object that owns the UDPClient is no longer in scope.I think my misunderstanding is from the documentation. `incoming network connections` sounds like it is listening for connection handshakes.NWConnection: A bidirectional data connection between a local endpoint and a remote endpoint. NWListener: An object you use to listen for incoming network connections.https://developer.apple.com/documentation/network/nwconnectionhttps://developer.apple.com/documentation/network/nwlistenerThat's all it says at the moment. So I cannot use NWConnection to listen for UDP messages?I'll go try out NWListener
Post not yet marked as solved
6 Replies
Same. @eskimo this code here doesn't seem to receive, it's effectively the same code but not using a timer to send, right? Is there something missing?class UDPClient { var connection: NWConnection var address: NWEndpoint.Host var port: NWEndpoint.Port var delegate: UDPListener? private var listening = true var resultHandler = NWConnection.SendCompletion.contentProcessed { NWError in guard NWError == nil else { print("ERROR! Error when data (Type: Data) sending. NWError: \n \(NWError!)") return } } init?(address newAddress: String, port newPort: Int32, listener isListener: Bool = true) { guard let codedAddress = IPv4Address(newAddress), let codedPort = NWEndpoint.Port(rawValue: NWEndpoint.Port.RawValue(newPort)) else { print("Failed to create connection address") return nil } address = .ipv4(codedAddress) port = codedPort listening = isListener connection = NWConnection(host: address, port: port, using: .udp) connect() } func connect() { connection.stateUpdateHandler = { newState in switch (newState) { case .ready: print("State: Ready") if self.listening { self.listen() } case .setup: print("State: Setup") case .cancelled: print("State: Cancelled") case .preparing: print("State: Preparing") default: print("ERROR! State not defined!\n") } } connection.start(queue: .global()) } func send(_ data: Data) { connection.send(content: data, completion: resultHandler) } private func listen() { while listening { connection.receiveMessage { data, context, isComplete, error in print("Receive isComplete: " + isComplete.description) guard let data = data else { print("Error: Received nil Data") return } print("Data Received") } } } }