<!--
{
  "availability" : [
    "iOS: 9.0.0 - 18.0.0",
    "iPadOS: 9.0.0 - 18.0.0",
    "macCatalyst: 13.1.0 - 18.0.0",
    "macOS: 10.11.0 - 15.0.0",
    "visionOS: 1.0.0 - 2.0.0"
  ],
  "documentType" : "symbol",
  "framework" : "NetworkExtension",
  "identifier" : "/documentation/NetworkExtension/NEAppProxyUDPFlow/readDatagrams(completionHandler:)-9z8gw",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Method",
  "symbol" : {
    "kind" : "Instance Method",
    "modules" : [
      "Network Extension"
    ],
    "preciseIdentifier" : "c:objc(cs)NEAppProxyUDPFlow(im)readDatagramsWithCompletionHandler:"
  },
  "title" : "readDatagrams(completionHandler:)"
}
-->

# readDatagrams(completionHandler:)

Read datagrams from the flow.

```
func readDatagrams(completionHandler: @escaping ([Data]?, [NWEndpoint]?, (any Error)?) -> Void)
```

## Parameters

`completionHandler`

A block that will be executed by the system on an internal system thread when datagrams have been read from the flow. The block takes the datagrams that were read, the destination endpoints of the datagrams, and an <doc://com.apple.documentation/documentation/Foundation/NSError>. If an error occurred while reading then `error` will be non-nil. See `NEAppProxyFlowError` in [`NEAppProxyFlow`](/documentation/NetworkExtension/NEAppProxyFlow) for a list of possible error codes. If the `datagrams` and `remoteEndpoints` arrays are non-nil but are empty, then no more datagrams can be subsequently read from the flow.
  
  > Note:
  > The completion handler is only called for the single read operation that was initiated by calling this method. If the caller wants to read more datagrams then it should call this method again to schedule another read operation and another execution of the completion handler block.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)