Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@tanner0101
Last active February 3, 2017 04:18
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tanner0101/73d0923efdee50e6c38f to your computer and use it in GitHub Desktop.
Save tanner0101/73d0923efdee50e6c38f to your computer and use it in GitHub Desktop.
Convert to and from NSData for common Swift types. Includes Eddystone URL conversion.
//
// NSData.swift
// Pods
//
// Created by Tanner Nelson on 9/15/15.
//
//
import Foundation
extension NSData {
var uint8: UInt8 {
get {
var number: UInt8 = 0
self.getBytes(&number, length: sizeof(UInt8))
return number
}
}
var uint16: UInt16 {
get {
var number: UInt16 = 0
self.getBytes(&number, length: sizeof(UInt16))
return number
}
}
var uint32: UInt32 {
get {
var number: UInt32 = 0
self.getBytes(&number, length: sizeof(UInt32))
return number
}
}
var uuid: NSUUID? {
get {
var bytes = [UInt8](count: self.length, repeatedValue: 0)
self.getBytes(&bytes, length: self.length * sizeof(UInt8))
return NSUUID(UUIDBytes: bytes)
}
}
var string: String {
get {
if let string = NSString(data: self, encoding: NSUTF8StringEncoding) {
return string as String
} else {
return ""
}
}
}
var stringUsingEddystoneUrlEncoding: String {
get {
//constants
let schemePrefixes = [
"http://www.",
"https:/www.",
"http://",
"https://"
]
let urlEncodings = [
".com/",
".org/",
".edu/",
".net/",
".info/",
".biz/",
".gov/",
".com",
".org",
".edu",
".net",
".info",
".biz",
".gov"
]
let count = self.length / sizeof(Int8)
var rawBytes = [Int8](count: count, repeatedValue: 0)
self.getBytes(&rawBytes, length:count * sizeof(Int8))
var urlString = ""
var bytes = [Int]()
for rawByte in rawBytes {
bytes.append(Int(rawByte))
}
for (offset, byte) in bytes.enumerate() {
switch offset {
case 0:
if byte < schemePrefixes.count {
urlString += schemePrefixes[byte]
}
case 1...bytes.count-1:
if byte < urlEncodings.count {
if byte < urlEncodings.count {
urlString += urlEncodings[byte]
} else {
urlString += String(byte)
}
} else {
let unicode = UnicodeScalar(byte)
let character = Character(unicode)
urlString.append(character)
}
default:
break
}
}
return urlString
}
}
}
extension Int {
var data: NSData {
var int = self
return NSData(bytes: &int, length: sizeof(Int))
}
}
extension UInt8 {
var data: NSData {
var int = self
return NSData(bytes: &int, length: sizeof(UInt8))
}
}
extension UInt16 {
var data: NSData {
var int = self
return NSData(bytes: &int, length: sizeof(UInt16))
}
}
extension UInt32 {
var data: NSData {
var int = self
return NSData(bytes: &int, length: sizeof(UInt32))
}
}
extension NSUUID {
var data: NSData {
var uuid = [UInt8](count: 16, repeatedValue: 0)
self.getUUIDBytes(&uuid)
return NSData(bytes: &uuid, length: 16)
}
}
extension String {
var dataUsingEddystoneUrlEncoding: NSData {
get {
var bytes = [UInt8]()
typealias EncodingPattern = (pattern: String, encoding: UInt8)
let urlSchemePrefixes: [EncodingPattern] = [
("https://www.", 1),
("http://www.", 0),
("https://", 3),
("http://", 2),
]
let urlEncodings: [EncodingPattern] = [
(".com/", 0),
(".org/", 1),
(".edu/", 2),
(".net/", 3),
(".info/", 4),
(".biz/", 5),
(".gov/", 6),
(".com", 7),
(".org", 8),
(".edu", 9),
(".net", 10),
(".info", 11),
(".biz", 12),
(".gov", 13),
]
var stringBuffer = self
//Look for http://, etc and replace with encoding
for prefix in urlSchemePrefixes {
if stringBuffer.hasPrefix(prefix.pattern) {
if let range = stringBuffer.rangeOfString(prefix.pattern) {
bytes.append(prefix.encoding)
stringBuffer.removeRange(range)
break
}
}
}
//For the rest of the string, loop through the
while(!stringBuffer.isEmpty) {
var foundEncoding = false
for urlEncoding in urlEncodings {
if stringBuffer.hasPrefix(urlEncoding.pattern) {
if let range = stringBuffer.rangeOfString(urlEncoding.pattern) {
bytes.append(urlEncoding.encoding)
stringBuffer.removeRange(range)
foundEncoding = true
break
}
}
}
if !foundEncoding {
for character in stringBuffer.unicodeScalars {
bytes.append( UInt8(character.value) )
stringBuffer = String(stringBuffer.characters.dropFirst())
break
}
}
}
return NSData(bytes: bytes, length: bytes.count)
}
}
}
extension String {
var data: NSData {
if let data = self.dataUsingEncoding(NSUTF8StringEncoding) {
return data
} else {
return NSData()
}
}
}
extension NSString {
var data: NSData {
if let data = self.dataUsingEncoding(NSUTF8StringEncoding) {
return data
} else {
return NSData()
}
}
}
@huguesbr
Copy link

👍 thx, I've customize it for my own need. https://gist.github.com/huguesbr/b2a316a4753093015a27

@adolfo
Copy link

adolfo commented Dec 5, 2016

Nice.

This could be simplified a bit by extending IntegerType instead of each individual integer type (Int, Uint, UInt8, Int8, UInt32, etc..)

extension IntegerType {
	var data: NSData {
		var varSelf = self
		return NSData(bytes: &varSelf, length: sizeofValue(self))
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment