Convert Data to DispatchData in Swift 4
Use withUnsafeBytes
to get an UnsafeRawPointer
to the data bytes,
create an UnsafeRawBufferPointer
from that pointer and the count,
and pass it to the DispatchData
constructor:
let formattedString = "A string"
let stringData = formattedString.data(using: .utf8)! // Cannot fail!
let data = stringData.withUnsafeBytes {
DispatchData(bytes: UnsafeRawBufferPointer(start: $0, count: stringData.count))
}
Alternatively, create an array from the Strings UTF-8 view and
use withUnsafeBytes
to get an UnsafeRawBufferPointer
representing the arrays contiguous element storage:
let formattedString = "A string"
let data = Array(formattedString.utf8).withUnsafeBytes {
DispatchData(bytes: $0)
}
How to convert dispatch_data_t to NSData?
For the most part, your code is correct. +initWithBytes:length:
will copy the buffer sent in so, you don't have to worry about freeing the buffer after the data, you can safely free the data first.
According to the documentation, you do NOT free the data after you are done with it:
If you specify non-NULL values for buffer_ptr or size_ptr, the values returned in
those variables are valid only until you release the newly created dispatch data
object. You can use these values as a quick way to access the data of the new
data object.
You simply release the new_data_file
variable (ARC will not do this for you).
Can the conversion of a String to Data with UTF-8 encoding ever fail?
UTF-8 can represent all valid Unicode code points, therefore a conversion
of a Swift string to UTF-8 data cannot fail.
The forced unwrap in
let string = "some string .."
let data = string.data(using: .utf8)!
is safe.
The same would be true for .utf16
or .utf32
, but not for
encodings which represent only a restricted character set,
such as .ascii
or .isoLatin1
.
You can alternatively use the .utf8
view of a string to create UTF-8 data,
avoiding the forced unwrap:
let string = "some string .."
let data = Data(string.utf8)
Delegating to another initializer from a closure
The problem with your extension is that although the compiler knows you're passing the closure as non-escaping argument to withUnsafeBytes(_:)
; it doesn't have any guarantee that it will be called once and only once (which is required for initialisation).
One simple solution is to, rather than chain to another initialiser, just construct a new instance of DispatchData
yourself, and then assign this to self
, thus completing initialisation:
import Foundation
private extension DispatchData {
init(data: Data) {
self = data.withUnsafeBytes { (typedPtr: UnsafePointer<UInt8>) in
DispatchData(bytes:
UnsafeRawBufferPointer(start: typedPtr, count: data.count)
)
}
}
}
Note also that there's an implicit conversion from UnsafePointer<UInt8>
to UnsafeRawPointer?
when passing it as an argument; so we don't need to wrap it in an initialiser call.
And in Swift 5, withUnsafeBytes
gives you a UnsafeRawBufferPointer
directly:
private extension DispatchData {
init(data: Data) {
self = data.withUnsafeBytes(DispatchData.init)
}
}
How do I get `Data` objects into Swift-NIO without making copies?
You'll need to import NIOFoundationCompat
to get any of NIO's method that work with Foundation
data types such as Data
(or JSONDecoder
/JSONEncoder
). NIOFoundationCompat
is just another module of the swift-nio
package so you won't need another dependency.
But just to be clear, under the hood, there will always be copies but probably you don't need to worry about them, copies are extremely fast on today's CPUs. If you absolutely want to avoid copies, you'll need to create ByteBuffer
s straight away. To help you with that, you may want to add where you get your data from that you want to send over the network.
Optional(OS_dispatch_data: data[0x7f97b145f2f0] = { leaf, size = 17290, buf = 0x11a63f000 })
Try correcting your do and catch..
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
@IBOutlet weak var lbl_studentID: UILabel!
@IBOutlet weak var image: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func btnfunc_getStudentID(sender: UIButton) {
let data:String = "http://neo4j.nannasgroup.com/service.php"
let url:NSURL = NSURL.init(string: data)!
let req:NSURLRequest = NSURLRequest.init(URL: url)
let res:AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
do {
let dataVal = try NSURLConnection.sendSynchronousRequest(req, returningResponse: res)
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(dataVal, options: []) as? NSMutableArray {
lbl_studentID.text = "\(jsonResult)"
}
} catch let error as NSError {
print(error.localizedDescription)
}
} catch let error as NSError {
print("incatch" + error.localizedDescription)
}
}
@IBAction func selectPicture(sender: UIButton) {
let ImagePicker = UIImagePickerController()
ImagePicker.delegate = self
ImagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
self.presentViewController(ImagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)
}
@IBAction func upload_request(sender: UIButton) {
}
}
Converting NSData(contentsOfUrl) to NSURLSession?
I'm afraid you cannot do what you describe. The contentsOfURL
method does not return until the entire file is transferred. If you have a slow connection or the file is large, the UI would appear to freeze as the main thread is busy. Only use that method for local files.
Looks like your second attempt has two issues:
First, for security reasons, you can only load secure (https:) URLs by default. See this note: https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/
Second, dataTaskWithURL
does not initiate the transfer; the dataTask won't do anything until you instruct it to start by calling task.resume()
. After all the data has been transferred, the closure code will be executed by a different thread. This is why you cannot return a value.
You can still create your datas array, but you need to move the declaration to the top level of your class. Remember the closure is executed by a different thread, so you will need to reference the array as self.datas
from within the closure.
If you need to update UI elements after the data has been loaded in the closure, you need to issue the update via the main thread. To force a table to display with the new data, you would add this to the end of the closure:self.myTable.performSelectorOnMainThread( "reloadData", withObject: nil, waitUntilDone: false)
How can I convert my UInt8 array to Data? (Swift)
It looks like you're really trying to avoid a copy of the bytes, if not, then just init a new Data with your bytes
array:
let data2 = Data(bytes)
print("data2: \(data2)")
If you really want to avoid the copy, what about something like this?
let data1 = Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: bytes), count: bytes.count, deallocator: .none)
print("data1: \(data1)")
How to convert (OS_dispatch_data *) 5018112 bytes into NSData to put into UIImage
NSData
is actually a class cluster which just provides the interface, and there are multiple special implementations for it around. It appears that OS_dispatch_data
is such a special implementations made to pass data objects around blocks, especially since your UIImage
creation doesn't crash (as it would if you would pass it a non NSData
object, or just garbage memory). Instead, it looks like UIImage
simply doesn't recognize the format the image is in!
By the way, Apple has a great guide about the concept of class clusters, which can be found here.
Related Topics
Swift Running Code in Periodically Background
In App Purchase in Skscene Not Working
Turn Off Touch for Whole Screen, Spritekit, How
Transparent Sticky Header UI Collectionview Don't Show Cells Underneath
Issue with Optional Core Data Relationship Using Nspersistentcloudkitcontainer
Uislider Handle Changes Width on Different Size Ipads
External Library Usage in Xcode
Get Out of Navigation Controller and Go Back to Tab Bar View
Choppy Animation Swiftui Nested Views
Swift Protocol That Is Using an Enum with Generic Associated Type
How to Hide The Top Bar (With Buttons) Usin Swift and Macos
Convert Data to Dispatchdata in Swift 4
Using a Swiftui List Sidebar in a UIsplitviewcontroller
Access Environment Variable Inside Global Function - Swiftui + Coredata
How to Set .Realm File on Realm
Why Run Loop Is Needed When Using Dispatchqueue.Main.Async in MAC Command Line Tool in Swift