A swiftier way to convert String to UnsafePointerxmlChar in Swift 3 (libxml2)
Swiftiest way I can think of is to just use the bitPattern:
initializer:
let xmlstr = str.utf8CString.map { xmlChar(bitPattern: $0) }
This will give you an Array
of xmlChar
s. Hang onto that, and use Array
's withUnsafeBufferPointer
method when you need to pass an UnsafePointer
to something:
xmlstr.withUnsafeBufferPointer { someAPIThatWantsAPointer($0.baseAddress!) }
Don't let the UnsafePointer
escape from the closure, as it won't be valid outside it.
EDIT: How's this for a compromise? Instead of having your function return a pointer, have it take a closure.
func withXmlString<T>(from string: String, handler: (UnsafePointer<xmlChar>) throws -> T) rethrows -> T {
let xmlstr = string.utf8CString.map { xmlChar(bitPattern: $0) }
return try xmlstr.withUnsafeBufferPointer { try handler($0.baseAddress!) }
}
Or, as an extension on String
:
extension String {
func withXmlString<T>(handler: (UnsafePointer<xmlChar>) throws -> T) rethrows -> T {
let xmlstr = self.utf8CString.map { xmlChar(bitPattern: $0) }
return try xmlstr.withUnsafeBufferPointer { try handler($0.baseAddress!) }
}
}
Swift convert string to UnsafeMutablePointerInt8
Previous answers on StackOverflow using CString don't seem to work anymore
Nevertheless, UnsafePointer<Int8>
is a C string. If your context absolutely requires an UnsafeMutablePointer
, just coerce, like this:
let s = NSBundle.mainBundle().bundlePath
let cs = (s as NSString).UTF8String
var buffer = UnsafeMutablePointer<Int8>(cs)
swe_set_ephe_path(buffer)
Of course I don't have your swe_set_ephe_path
, but it works fine in my testing when it is stubbed like this:
func swe_set_ephe_path(path: UnsafeMutablePointer<Int8>) {
println(String.fromCString(path))
}
How can I convert a String to an MD5 hash in iOS using Swift?
There are two steps:
1. Create md5 data from a string
2. Covert the md5 data to a hex string
Swift 2.0:
func md5(string string: String) -> String {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
CC_MD5(data.bytes, CC_LONG(data.length), &digest)
}
var digestHex = ""
for index in 0..<Int(CC_MD5_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}
return digestHex
}
//Test:
let digest = md5(string:"Hello")
print("digest: \(digest)")
Output:
digest: 8b1a9953c4611296a827abf8c47804d7
Swift 3.0:
func MD5(string: String) -> Data {
let messageData = string.data(using:.utf8)!
var digestData = Data(count: Int(CC_MD5_DIGEST_LENGTH))
_ = digestData.withUnsafeMutableBytes {digestBytes in
messageData.withUnsafeBytes {messageBytes in
CC_MD5(messageBytes, CC_LONG(messageData.count), digestBytes)
}
}
return digestData
}
//Test:
let md5Data = MD5(string:"Hello")
let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")
let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")
Output:
md5Hex: 8b1a9953c4611296a827abf8c47804d7
md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==
Swift 5.0:
import Foundation
import var CommonCrypto.CC_MD5_DIGEST_LENGTH
import func CommonCrypto.CC_MD5
import typealias CommonCrypto.CC_LONG
func MD5(string: String) -> Data {
let length = Int(CC_MD5_DIGEST_LENGTH)
let messageData = string.data(using:.utf8)!
var digestData = Data(count: length)
_ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
messageData.withUnsafeBytes { messageBytes -> UInt8 in
if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
let messageLength = CC_LONG(messageData.count)
CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
}
return 0
}
}
return digestData
}
//Test:
let md5Data = MD5(string:"Hello")
let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")
let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")
Output:
md5Hex: 8b1a9953c4611296a827abf8c47804d7
md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==
Notes:#import <CommonCrypto/CommonCrypto.h>
must be added to a Bridging-Header file
For how to create a Bridging-Header see this SO answer.
In general MD5 should not be used for new work, SHA256 is a current best practice.
Example from deprecated documentation section:
MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512 (Swift 3+)
These functions will hash either String or Data input with one of eight cryptographic hash algorithms.
The name parameter specifies the hash function name as a String
Supported functions are MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384 and SHA512
a
This example requires Common Crypto
It is necessary to have a bridging header to the project:#import <CommonCrypto/CommonCrypto.h>
Add the Security.framework to the project.
This function takes a hash name and String to be hashed and returns a Data:
name: A name of a hash function as a String
string: The String to be hashed
returns: the hashed result as Data
func hash(name:String, string:String) -> Data? {
let data = string.data(using:.utf8)!
return hash(name:name, data:data)
}
Examples:
let clearString = "clearData0123456"
let clearData = clearString.data(using:.utf8)!
print("clearString: \(clearString)")
print("clearData: \(clearData as NSData)")
let hashSHA256 = hash(name:"SHA256", string:clearString)
print("hashSHA256: \(hashSHA256! as NSData)")
let hashMD5 = hash(name:"MD5", data:clearData)
print("hashMD5: \(hashMD5! as NSData)")
Output:
clearString: clearData0123456
clearData: <636c6561 72446174 61303132 33343536>
hashSHA256: <aabc766b 6b357564 e41f4f91 2d494bcc bfa16924 b574abbd ba9e3e9d a0c8920a>
hashMD5: <4df665f7 b94aea69 695b0e7b baf9e9d6>
Populating MTLBuffer with 16-bit Floats
Half-precision floats in Swift are very awkward, since there is no Float16
type yet (though one has been proposed) and the nonstandard __fp16
type supported by Clang isn't fully supported in Swift either.
Through the magic of type-punning and bridging headers, however, you may be able to cobble together a workable solution.
The basic approach is this: In an Objective-C header, declare a half2
type with two uint16_t
members. These will be our storage type. Also declare a function that takes a float and writes it as if it were a __fp16
to a pointer-to-uint16_t
:
typedef struct {
uint16_t x, y;
} half2;
static void storeAsF16(float value, uint16_t *_Nonnull pointer) { *(__fp16 *)pointer = value; }
Back in Swift, you can declare a typealias and use it in your particle struct definition:
typealias Half2 = half2
struct Particle {
var position: Half2
}
(Here I'm typealiasing from the lower-case type to a Swiftier name; you could skip this and just name the Obj-C type Half2
if you prefer).
Instead of binding to the particle type, you'll need to bind the buffer to your half vector type instead:
var pointer = particleBuffer.contents().bindMemory(to: Half2.self, capacity: particleCount)
When we use our utility function to store a float, the bit pattern for the corresponding half value gets written to the UInt16
:
var x: UInt16 = 0
var y: UInt16 = 0
storeAsF16(1.0, &x) // 0x3c00
storeAsF16(0.5, &y) // 0x3800
Now that we have correctly-formated half values in this pair of variables, we can write them into the buffer:
pointer.pointee = Half2(x: x, y: y)
Note that this approach is neither portable nor safe, especially because Swift doesn't make any guarantees about struct member layout. There may be other less cumbersome approaches, too; this is just what has worked for me in the past.
Swift equivalent to Objective-C FourCharCode single quote literals (e.g. 'TEXT')
I'm using this in my Cocoa Scripting apps, it considers characters > 0x80 correctly
func OSTypeFrom(string : String) -> UInt {
var result : UInt = 0
if let data = string.dataUsingEncoding(NSMacOSRomanStringEncoding) {
let bytes = UnsafePointer<UInt8>(data.bytes)
for i in 0..<data.length {
result = result << 8 + UInt(bytes[i])
}
}
return result
}
Edit:
Alternatively
func fourCharCodeFrom(string : String) -> FourCharCode
{
assert(string.count == 4, "String length must be 4")
var result : FourCharCode = 0
for char in string.utf16 {
result = (result << 8) + FourCharCode(char)
}
return result
}
or still swiftier
func fourCharCode(from string : String) -> FourCharCode
{
return string.utf16.reduce(0, {$0 << 8 + FourCharCode($1)})
}
What is the swift equivalent to setting properties on `id`?
In Swift 2.0 beta 4, your prayers are answered; this code becomes legal:
@IBAction
func handleEvent(sender: AnyObject) {
if sender.respondsToSelector("setHidden:") {
sender.performSelector("setHidden:", withObject: true)
}
}
observing contentSize (CGSize) with KVO in swift
Are you on iOS? Because I am, I did the same thing and arrived at the same question; why NSSize
? Maybe that's just the xcode terminal playing a trick on us.
Anyway, you can cast it to an NSValue
then you will be able to use CGSizeValue
:
if let zeChange = change as? [NSString: NSValue] {
let oldSize = zeChange[NSKeyValueChangeOldKey]?.CGSizeValue()
let newSize = zeChange[NSKeyValueChangeNewKey]?.CGSizeValue()
}
Related Topics
Swift Packages and Conflicting Dependencies
Libicuuc.So.55: Cannot Open Shared Object File
Detect When Wkwebview Is Finished Loading
How to Implement Default Associated Values with Swift Enums
Xcode Takes Long Time to Print Debug Results
Swiftui Sheet Not Animating Dismissal on MACos Big Sur
Uirefreshcontrol() in iOS 11 Glitchy Effect
Iterating Over an Nsorderedset
Gmsplace Returns Invalid Coordinate (-180, -180), But Name and Place Id Are Correct
Captureoutput Function Isn't Called Using Setsamplebufferdelegate
How to Access Cfdictionary in Swift 3
"Use Default Container" Doesn't Show in Icloud Capabilities
Swift "Is" Operator with Type Stored in Variable
Swift Find Superview of Given Class with Generics
Adding a Custom Font to MACos App Using Swift
How to Remove Top Space of 'Form' in Swiftui
In What Situation Would One Use Expectationfornotification in Swift Testing
How to Change Default Background Color of Callout Bubble with Detailcalloutaccessoryview