2
class Facts {
    var networkOperaton = NetworkOperation(url: "http://fact.tayfunturanligil.com")
    var factsArray : [String] = []
    init () {
        self.networkOperaton.downloadJSONFromURL({
            (a:[String]) -> [String] in
            println(a)
            self.factsArray = a
            return a
        })
    }
}

When I want to create an instance of Facts in my ViewController using var facts = Facts(), factsArray stays as an empty array. But it should be getting an array from downloadJSONFromURL function. Why this is happening? Even my println(a) is not called.

I tested downloadJSONFromURL function in a playground and it works. Also, networkOperation uses NSURLSession, could this be an issue?

3
  • Did you have a question? Commented Aug 16, 2015 at 9:59
  • Sorry for not being clear. I want my factsArray to be assigned an array but it does not. I think my entire init function is not being called because println(a) is never called. Why this might be happening? Commented Aug 16, 2015 at 10:05
  • Put print test just after init, not in the part below Commented Aug 16, 2015 at 10:10

2 Answers 2

1

The init() method is actually called. Try out this code:

class Facts {
   var factsArray : [String] = []
   init () {
       println("Init called")
       factsArray = ["Hello", "World", "Bye", "World"]
   }
}

ViewController.swift:

override func viewDidLoad() {
    super.viewDidLoad()

    var facts = Facts()
    println(facts.factsArray)
}

The problem with your code would be that network operation would be running in asynchronous mode. Instead of making network request in init method you can define another method in function which can then return status of request in completion block.

func updateArrayFromNetwork(completion: (Bool) -> ()) {
    var networkOperaton = NetworkOperation(url: "http://fact.tayfunturanligil.com")
    self.networkOperaton.downloadJSONFromURL({
        (a:[String]) -> [String] in
        println(a)
        self.factsArray = a
        completion(true)
    })
}

ViewController.swift

override func viewDidLoad() {
    super.viewDidLoad()

    var facts = Facts()
    println(facts.factsArray)

    facts.updateArrayFromNetwork { (completed: Bool) -> () in
        if completed {
            //Do something
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Thats solved the problem. but a couple new problems appeared. 1) the app is incredibly slow now( it is fast if I use NSData insted of NSURLSeesion. 2) I have a println("network init done") statement in my networkOperation init() but I see network init done statement twice. 3) dont I need to use dispatch_async(dispatch_get_main_queue() function somewere. Again thanks for the help
NSData(contentsOfURL: NSURL, options: NSDataReadingOptions, error: NSErrorPointer) is generally meant to load data from local url (Documents folder or any other file from local storage. You must use NSURLSession's sendAsynchronousRequest: [link][1] [1]:developer.apple.com/library/ios/documentation/Cocoa/Reference/…:
0

init() is called but downloadJSONFromURL() is an asynchronous method.
That means init() returns immediately the Facts instance after calling downloadJSONFromURL() without waiting for completion.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.