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")
}
}
}
}
Post
Replies
Boosts
Views
Activity
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
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))
}
}
}
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}
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!")
}
}
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.
Confirmed no way to do this. Please submit your own bug report for this. Duplicate question I asked a year later without realizing it: https://developer.apple.com/forums/thread/696320
Anyone know how I can upload or capture the data of the video stream to debug with others? I would use one of my code-level support tickets but I don't know if I can provide them the data
Is this a crash on the preview or a crash on the physical device and/or simulator?
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
It was accepted. Hope this helps anyone with a similar issue in the future.
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)
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.
@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())