4

I found answers to my question in Objective C but couldnt find it in Swift. How can I make the code below work in terms of adding a String value to an NSMutableString? It throws "length only defined for abstract class" error.

This code is aimed to parse an xml feed and write it to a NSMutableDictionary()

var ftitle = NSMutableString?()
func parser(parser: NSXMLParser!, foundCharacters string: String!) {
if element.isEqualToString("title") {
        ftitle?.appendString(string)
    }
}

Edit: Here is more context;

element is NSString which is assigned to elementName in parser during DidStartElement. in this code, i catch the "title" of the feed content via element.

i have an NSMutableDictionary() which includes different NSMutableString() such as ftitle. this piece of code is to add the string to the ftitle, which is NSMutableString, then it will be part of NSMutableDictionary, and finally i will read it to write in my tableviewcells

here is didStartElement method:

func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
    element = elementName

    if (element as NSString).isEqualToString("item"){
        elements = NSMutableDictionary.alloc()
        elements = [:]
        ftitle = NSMutableString.alloc()
        link = ""
        fdescription = NSMutableString.alloc()
        fdescription = ""
    }
}
johncoffey
  • 251
  • 3
  • 12
  • There are a couple of things missing in your question, for example: What is "element"?. Also you said that you want to append texto to a string but then you also said that you want to write a dictionary?. – fz. Feb 08 '15 at 06:48
  • I have to second that we need more information since you can concat String and NSString simply with the + operator. – Alex Feb 08 '15 at 07:04
  • sorry for lack of context, here is more: element is NSString which is assigned to elementName in parser during DidStartElement. in this code, i catch the "title" of the feed content via element. i have an NSMutableDictionary() which includes different NSMutableString() such as ftitle. this piece of code is to add the string to the ftitle, which is NSMutableString, then it will be part of NSMutableDictionary, and finally i will read it to write in my tableviewcells – johncoffey Feb 08 '15 at 07:31
  • 1
    what is the purpose of the `?` in `var ftitle = NSMutableString?()`? I've never seen such a construct in Swift. What happens if you replace it with `var ftitle = NSMutableString()` – Matthias Bauch Feb 08 '15 at 07:47
  • @MatthiasBauch: i need to check if the value coming from xml is nil or not in didEndElement. to do so, i need to use ? which indicates that the value might be also nil. – johncoffey Feb 08 '15 at 08:06
  • @johncoffey: Can you try to reduce the problem to a minimal reproducible example? Because `var ftitle = NSMutableString?(); ftitle?.appendString("foo") ; println(ftitle)` compiles and runs without problems (and prints "nil" as expected). Where/how to you assign a value to `ftitle`? – Martin R Feb 08 '15 at 08:10
  • @MatthiasBauch: `var ftitle = NSMutableString?()` is equivalent to `var ftitle : NSMutableString? = nil` . – Martin R Feb 08 '15 at 08:11
  • @MartinR: good point. i used println(string) to see if anything is wrong with string but no problem with it, i was able to see the string content of the feed successfully. i think the problem is the length difference between String and NSMutableString. fix for obj c was explained here: http://stackoverflow.com/questions/9180671/how-to-append-a-string-to-nsmutablestring but i dont know how to fix it in swift – johncoffey Feb 08 '15 at 08:25
  • @johncoffey: `var ftitle = NSMutableString?()` declares an optional mutable string and initializes it to `nil`, so that `ftitle?.appendString("foo")` simply does *nothing*. You probably want to set `ftitle = ""` in the `didStartElement` method. But failing to do so does not explain the "length only defined for abstract class" error. Therefore, as I said, a [SSCCE](http://sscce.org) is needed. Some lines of code that we can just copy into an Xcode project to reproduce the problem. – Martin R Feb 08 '15 at 08:30
  • @johncoffey: Btw, [here](http://stackoverflow.com/a/28217011/1187415) is an example how to work with mutable Swift strings instead of NSMutableString. – Martin R Feb 08 '15 at 08:46
  • @AndréDaniel: xcode6 has significant differences even with xcode6 beta when it comes to swift as we all know. thats why i used xcode6 tag to clarify that. – johncoffey Feb 08 '15 at 09:22
  • @johncoffey but unless the question is about Xcode's feature or bug, you shouldn't use that tag. Here we're talking about the language, and the language stays the same no matter if you write your code in Xcode or Sublime Text. –  Feb 08 '15 at 09:25

2 Answers2

6
ftitle = NSMutableString.alloc()

is not a correct way to assign an empty string. It allocates the NSMutableString without initializing it. NSMutableString is a class cluster, so this can cause all kinds of strange errors.

In Swift, you just would do

ftitle = NSMutableString()

or simply

ftitle = ""

For the same reason,

elements = NSMutableDictionary.alloc()

is wrong and should be

elements = NSMutableDictionary()
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
2

Unless I totally misunderstood what you are attempting to do, the following code is probably a cleaner Swift implementation. A string declared with a var is mutable. A string declared with `let' is immutable. Not sure when it is appropriate to use NSMutableString. Perhaps when you have a mixed Swift / Obj-C project.

    var ftitle = "" // declare ftitle as an empty string
var element = "" // this is coming from some other function
func parser(parser: NSXMLParser!, foundCharacters myString: String!) {
    if element == "title" {
        ftitle += myString // appends element to ftitle
    }
}
Syed Tariq
  • 2,878
  • 3
  • 27
  • 37