How do you initialize NSXMLDocument with an XML string in Swift? - swift

I'm trying to acquire values from an xml string, but being new to Swift I can't figure out how to initialize the NSXMLDocument object. I'm trying:
var xmlString:String = "<?xml version=\"1.0\"><results><item1><name>Something</name><price>10.99</price></item1></results>"
var xml:NSXMLDocument = NSXMLDocument(xmlString)
I'm getting the error "Cannot find an overload for 'init' that accepts the supplied arguments". I've tried converting the string to NSData but I end up with the same error:
var nsData:NSData = xmlString.dataUsingEncoding(NSUTF8StringEncoding)
var xml:NSXMLDocument = NSXMLDocument(nsData)

NSXMLDocument doesn't contain an initializer than only takes a string as a parameter. There is initWithXMLString:options:error: though, which should solve your problem. Something like:
let xmlString = "<?xml version=\"1.0\"><results><item1><name>Something</name><price>10.99</price></item1></results>"
var error: NSError?
let xml = NSXMLDocument(XMLString: xmlString, options: 0, error: &error)

Related

set finder tags from swift?

I can get finder tags in swift using the following code:
if let tagArray = try url.resourceValues(forKeys:[.tagNamesKey]).tagNames {
...
}
But setting it will result in an error:
var values = URLResourceValues()
values.tagNames = finderTags
Gives the error:
Compile Swift Module 'tagsync' (1 sources)
main.swift:104:20: error: cannot assign to property: 'tagNames' is a get-only property
values.tagNames = finderTags
~~~~~~~~~~~~~~~ ^
How can one write the tags from swift?
You can write Finder tags easily by using NSURL (not URL):
let myPath = "any POSIX path; spaces ok"
var myFinderTags = ["a", "b", "c"]
try NSURL(fileURLWithPath: myPath).setResourceValues([.tagNamesKey: myFinderTags])
The only way I know of to do it is to write the com.apple.metadata:_kMDItemUserTags extended attribute, which you can do using the setxattr API.

Swift 2.0: Type of Expression is ambiguous without more context? SortInPlace

This error occured in SWIFT 2.0. There are a lot of similar error messages, but I couldn't match them to my code:
class fileObj : Comparable {
var URL = NSURL()
var path = String()
var filename = String()
var fileExtension = String()
...
}
...
var images = [fileObj]() // array of all files (images)
images.sortInPlace( { $0.URL.absoluteString! > $1.URL.absoluteString! } ) // sort by name
The last row causes the error message, indicating, that $0 is wrong. Any idea?
NSURL's absoluteString is non-optional and you're force unwrapping it.
Rewrite the sort as follows
images.sortInPlace( { $0.URL.absoluteString > $1.URL.absoluteString } )

Correct way of casting types of a plist dictionary

I am loading a dictionary of dictionaries from a plist file like so:
var dict:NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("ISA", ofType: "plist"){
dict = NSDictionary(contentsOfFile: path)
}else{
println("Could not load ISA file")
}
Given that I know the form of the dictionary, at which point should I cast its type? For example should i do:
return dict as [String : [String : Int]]
Or would it be better to return an NSDictionary and then cast the types as I use them:
dict.allKeys as [String]
EDIT:
If I do it the first way I run into trouble later when I try to access the keys:
var keys = d.keys
var length0 = keys[0].utf16Count
Produces the error:
LazyBidirectionalCollection<MapCollectionView<Dictionary<String,[String,Int]>,String>> is not convertible to [String]
Many thanks, Ben

cannot convert a dictionary's int-value to String in swift

I have a webService, which is returning some data. here is the link http://portal.pfs-ltd.org/LoginService1114?deviceid=89A04BDB-53AA-4441-9AFD-287729ACFE7F&imeino=12345678&SerialNo=f7pln20mfpfl&username=TST0002&password=TST0002&type=agent&status=Login&flag=True&Brand=Ipad&SimSerialNumber=&TelePhoneNumber=&Model=0&InstalledVersion=1.0
I'm unable to convert the value(int) for a key to a var of type String
var ApplicationVersion: String = dict["ApplicationVersion"] as String
as is for typecasting, not converting. You need to make a string from the integer value:
let version = dict["ApplicationVersion"] as Int
let applicationVersion = "\(version)"
Note that this performs no safety checking or validation.
Your json is not a dictionary, but a nested array.
let json: [AnyObject] = ...
let dict = json[0][0] as NSDictionary
var applicationVersion = String(dict["ApplicationVersion"] as Int)

How to correctly initialize an UnsafePointer in Swift?

I'm trying to use CTFontCreatePathForGlyph(font: CTFont?, glyph: CGGlyph, transform: CConstPointer<CGAffineTransform>):
let myFont = CTFontCreateWithName("Helvetica", 12, nil)
let myGlyph = CTFontGetGlyphWithName(myFont, "a")
let myTransform = CGAffineTransformIdentity
But how do I correctly pass myTransform to CTFontCreatePathForGlyph?
I've tried creating a myTransformPointer to pass to the function like so:
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer().initialize(newvalue: myTransform)
but I get this error:
Playground execution failed: error: <REPL>:20:76: error: '()' is not convertible to 'UnsafePointer<CGAffineTransform>'
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer().initialize(newvalue: myTransform)
so then I tried explicitly naming the type:
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer<CGAffineTransform>().initialize(newvalue: myTransform)
and then I get a different error:
Playground execution failed: error: <REPL>:20:95: error: could not find an overload for 'init' that accepts the supplied arguments
var myTransformPointer: UnsafePointer<CGAffineTransform> = UnsafePointer<CGAffineTransform>().initialize(newvalue: myTransform)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The auto-complete suggests this should work?
The simplest solution is using withUnsafePointer function:
let myFont = CTFontCreateWithName("Helvetica", 12, nil)
let myGlyph = CTFontGetGlyphWithName(myFont, "a")
var myTransform = CGAffineTransformIdentity
var path = withUnsafePointer(&myTransform) { (pointer: UnsafePointer<CGAffineTransform>) -> (CGPath) in
return CTFontCreatePathForGlyph(myFont, myGlyph, pointer)
}
The initialize is not a constructor. You would have to alloc a new memory using UnsafePointer<T>.alloc, then initialize and then dealloc. Function withUnsafePointer does that all for you.
Note that myTransform cannot be a constant (var not let) otherwise you cannot use it for an inout param (&myTransform).