CheatyXML is a Swift framework designed to make working with XML easy and intuitive.
- iOS 8.0 or later
- tvOS 9.0 or later
If you're using CocoaPods, add the following to your Podfile
:
pod 'CheatyXML'
Then run:
pod install
To install manually:
- Add the
CheatyXML.xcodeproj
to your project. - Link the
CheatyXML.framework
in your target’s Linked Frameworks and Libraries section. - Import CheatyXML in your Swift code:
import CheatyXML
We'll use the following sample XML throughout our examples:
<blog version="1.0" creator="lobodart">
<name>MyAwesomeBlog!</name>
<users>
<admin is_active="true">lobodart</admin>
<moderator is_active="false">slash705</moderator>
<moderator is_active="...">...</moderator>
</users>
<article>
<title>My first article</title>
<description>This is the first article</description>
<infos>
<date>2015-03-15 15:42:42</date>
<rate>42</rate>
</infos>
</article>
<article>
...
</article>
</blog>
let parser = CXMLParser(contentsOfURL: url)
let parser = CXMLParser(string: xmlString)
let parser = CXMLParser(data: xmlData)
let blogName = parser["name"].stringValue // Returns a non-optional String
let blogNameOptional = parser["name"].string // Returns an optional String
You can also use rootElement
for clarity:
let element = parser.rootElement["name"]
let blogAdmin = parser["users"]["admin"].stringValue
print(blogAdmin) // lobodart
let title1 = parser["article", 0]["title"].stringValue
let title2 = parser["article"][0]["title"].stringValue
Both notations are equivalent—choose whichever you prefer.
for element in parser.rootElement {
print(element.tagName)
}
Output:
name
users
article
article
for article in parser.rootElement.elementsNamed("article") {
print(article.tagName)
}
let childCount = parser["users"].numberOfChildElements
print(childCount) // 4 (3 moderators + 1 admin)
let moderatorCount1 = parser["users"]["moderator"].count
let moderatorCount2 = parser["users"].elementsNamed("moderator").count
CheatyXML supports casting to common types:
let rate = parser["article", 0]["rate"]
rate.int // Optional(42)
rate.intValue // 42
rate.float // Optional(42.0)
rate.floatValue // 42.0
Always prefer optional casts when unsure about the value:
let title = parser["article", 0]["title"]
title.string // Optional("My first article")
title.stringValue // "My first article"
title.int // nil
title.intValue // ⚠️ CRASH!
let date = parser["article", 0]["infos"]["date"].stringValue
print(date) // "2015-03-15 15:42:42"
let missingDate = parser["articles", 0]["infos"]["date"].string
print(missingDate) // nil
💡 Tip: Use
.string
(optional) over.stringValue
(non-optional) to safely avoid crashes on missing tags.
let version = parser.rootElement.attribute("version")
let isActive = parser["users"]["admin"].attribute("is_active")
With type casting:
let version = parser.rootElement.attribute("version").floatValue // 1.0
let creator = parser.rootElement.attribute("creator").stringValue // "lobodart"
let attributes = parser.rootElement.attributes // [CXMLAttribute]
let dict = attributes.dictionary // [String: String]
- Add more unit tests
- Class mapping
- XML generator