I am attempting to pull out and print two values from CoreData. One is speed, the other is degrees. However things don't go as planned. First up, here's part of the code:
// Start fetching from CoreData
request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result: AnyObject in results! {
println(result)
println(result.speed)
println(result.degrees)
}
}
else {
println("No data")
}
When I simply print results I get the values:
<NSManagedObject: 0x7f944a734e80> (entity: WindData; id: 0xd000000000740000 <x-coredata://762EB8C2-DDCF-43F5-8DFC-FAB9A29532E1/WindData/p29> ; data: {
degrees = 190;
speed = 8; })
println(result.speed) writes in the consol: 2.34181e-38
and println(result.degrees) won't allow me to compile and tells me that AnyObject does not have a member named degrees (although it clearly does)
Sorry for any rookie mistakes, this is my first time posting on Stackoverflow.
Here is the full code:
//
// ViewController.swift
// KitesurfioApp
//
// Created by Lasse Kristensen on 24/10/14.
// Copyright (c) 2014 Lasse Kristensen. All rights reserved.
//
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Set logo in nav bar
navigationItem.titleView = UIImageView(image: UIImage(named: "logo"))
// Global save values
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
// JSON Fetching
let urlPath = "http://api.openweathermap.org/data/2.5/weather?lat=55.564120&lon=12.568605"
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
}
else {
// Delete old entries in CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
for result in results! {
context.deleteObject(result as NSManagedObject)
context.save(nil)
}
// Start fetching JSON
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var item = jsonResult["wind"] as NSDictionary
var degrees:Int = item["deg"] as NSInteger
var speed:Float = item["speed"] as Float
// Start saving JSON
var newItem = NSEntityDescription.insertNewObjectForEntityForName("WindData", inManagedObjectContext: context) as NSManagedObject
var speedValue:NSNumber = speed as NSNumber
var degreesValue:NSNumber = degrees as NSNumber
newItem.setValue(speedValue, forKey: "speed")
newItem.setValue(degreesValue, forKey: "degrees")
context.save(nil)
}
})
task.resume()
// Start fetching from CoreData
var request = NSFetchRequest(entityName: "WindData")
request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result: AnyObject in results! as [WindData] {
println(result)
println(result.speed)
}
}
else {
println("No data")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You need to cast the AnyObject to your class which have properties degree etc.AnyObject does not know about your class properties you need to downcast the array [AnyObject] to your class array
for result in results! as [NSManagedObject] {
println(result)
println(result.valueForKey("speed")!)
println(result.valueForKey("degrees")!)
}
Related
I'm trying to make an array from my Viewcontroller equal to, the objects my core data has saved. I'm using core data and created an entity named Pokemon which has 3 attributes name, id and generation. In the app delegate, I use the following function to get Pokemon from this API. This is what I do to parse the data and save the context:
typealias DownloadCompleted = () -> ()
var pokemonId: Int16 = 0
func fetchPokemon(url: String, completed: #escaping DownloadCompleted) {
let context = coreData.persistentContainer.viewContext
let url = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: url) { (data, repsonse, error) in
if error != nil {
print(error!)
}
do {
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
let jsonArray = jsonResult.value(forKey: "results") as! [[String: Any]]
for pokemonData in jsonArray {
self.pokemonId += 1
if self.pokemonId > 721 {
self.coreData.saveContext()
return
}
guard let name = pokemonData["name"] as? String else {
return
}
let pokemon = Pokemon(context: context)
pokemon.name = name
pokemon.id = self.pokemonId
print("Name: \(pokemon.name) Id:\(self.pokemonId)")
if self.pokemonId <= 151 {
pokemon.generation = 1
} else if self.pokemonId <= 251 {
pokemon.generation = 2
} else if self.pokemonId <= 386 {
pokemon.generation = 3
} else if self.pokemonId <= 493 {
pokemon.generation = 4
} else if self.pokemonId <= 649 {
pokemon.generation = 5
} else if self.pokemonId <= 721 {
pokemon.generation = 6
}
}
guard let nextURL = jsonResult.value(forKey: "next") as? String else {
self.coreData.saveContext()
return
}
DispatchQueue.main.async {
self.fetchPokemon(url: nextURL, completed: {
self.coreData.saveContext()
})
completed()
}
} catch let err {
print(err.localizedDescription)
}
}
task.resume()
}
This is how I call it in the appDelegate. Really don't know what to do in the middle of the fetchPokemon or how to call it in another view controller. So I left it blank, not sure if this has something to do with the problem I'm having.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let context = self.coreData.persistentContainer.viewContext
let pokemonListVC = self.window?.rootViewController as! PokemonListVC
pokemonListVC.context = context
fetchPokemon(url: pokemonAPI) {
}
return true
}
Im using this SQL-Light read-only app from the app store. I check the data and all 721 pokemon are saving. Now, I don't know how I would be able to make the array in my view controller equal to all 721 Pokemon saved. I added this code into my viewController.
class PokemonListVC: UIViewController {
weak var context: NSManagedObjectContext! {
didSet {
return pokemon = Pokemon(context: context)
}
}
var pokemon: Pokemon? = nil
lazy var pokemons = [Pokemon]()
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
func loadData() {
pokemons = pokemon!.loadPokemon(generation: 1, context: context)
}
}
I've created an extension of my Pokemon entity and added a function loadPokemon that filters the Pokemon by generation. Here is the code.
extension Pokemon {
func loadPokemon(generation: Int16 = 0, context: NSManagedObjectContext) -> [Pokemon] {
let request: NSFetchRequest<Pokemon> = Pokemon.fetchRequest()
request.predicate = NSPredicate(format: "generation = %#", generation)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
do {
let pokemons = try context.fetch(request)
print("My Pokemon count: \(pokemons.count)")
return pokemons
} catch let err {
print(err.localizedDescription)
}
return []
}
}
When I call the loadData in my ViewController it crashes. The array count is 0 and so is the one in the hero extension. So I don't how to make my array equal the Pokemon saved from coreData.
Would really appreciate any help provided. :)
Here is my deleteRecords code, which is also in my appDelegate. This deletes all records when app launches. I call this method at the very beginning of didFinishLaunchingWithOption function before the fetchPokemons.
func deleteRecords() {
let context = coreData.persistentContainer.viewContext
let pokemonRequest: NSFetchRequest<Pokemon> = Pokemon.fetchRequest()
var deleteRequest: NSBatchDeleteRequest
var deleteResults: NSPersistentStoreResult
do {
deleteRequest = NSBatchDeleteRequest(fetchRequest: pokemonRequest as! NSFetchRequest<NSFetchRequestResult>)
deleteResults = try context.execute(deleteRequest)
} catch let err {
print(err.localizedDescription)
}
}
As you are saying that you have sure that all the pockemon records are stored correctly in your coredata you can simply fetch records from your codedata by providing fetch request. I have created demo for contact storing and I can get all the contact by this fetch request you can try this code in your ViewController where you want to fetch all the record.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject> (entityName: "Pokemon")
do {
arrPockemon = try managedContext.fetch(fetchRequest)
}catch let error as NSError {
showAlert(string: error.localizedDescription)
}
try to get all records first and if you get all then work for filtering extension and all. hope it will help you. you can learn from here https://code.tutsplus.com/tutorials/core-data-and-swift-core-data-stack--cms-25065
save flag on userDefault.
//check for first time when app is installed first time(first time flag is not present so)
let userDefault = UserDefaults.standard.dictionaryRepresentation()
if userDefault.keys.contains("isDataAvailable") {
//key is availebe so check it
if userDefault["isDataAvailable"] as! String == "1"{
//no need to call server for data
}else{
//fetch data from server
// once you get data from server make isDataAvailable flage as 1
UserDefaults.standard.setValue("1", forKey: "isDataAvailable")
UserDefaults.standard.synchronize()
}
}
else{
//flag is not avalable so call server for data
// once you get data from server make isDataAvailable flage as 1
UserDefaults.standard.setValue("1", forKey: "isDataAvailable")
UserDefaults.standard.synchronize()
}
I am getting the following error while trying to do NSFetchRequest in Swift 3
Generic parameter 'ResultType' could not be inferred
i checked lots of links and i have not been able to figure how to solve it.
this is what am doing
ViewController.swift
func loadData(){
let request = NSFetchRequest(entityName: "Grocery") //Error occurs here(Generic parameter 'ResultType' could not be inferred)
do{
let results = try manageObjectContext.execute(request)
groceries = results as! [NSManagedObject]
tableView.reloadData()
}catch{
fatalError("Error is retriving Gorcery items")
}
}
Try this:
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Grocery")
It should work :)
Therefore your code should Look like:
func loadData(){
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Grocery")
do{
let results = try manageObjectContext.execute(request)
groceries = results as! [NSManagedObject]
tableView.reloadData()
}catch{
fatalError("Error is retriving Gorcery items")
}
}
Credits: Nitesh Patil https://medium.com/#imnitpa/swift-3-core-data-7b00b50f5782
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let appDelegate = UIApplication.shared.delegate as!AppDelegate
let context = appDelegate.persistentContainer.viewContext
//adding new user and saving in database...
let newUser = NSEntityDescription.insertNewObject(forEntityName: "Users", into: context)
newUser.setValue("Batman", forKey: "username")
newUser.setValue("Robin", forKey: "password")
do {
try context.save()
print("saved")
} catch {
print("Error occured...")
}
// restoring data back from database
let request = NSFetchRequest < NSFetchRequestResult > (entityName: "Users")
request.returnsObjectsAsFaults = false
do {
let results =
try context.fetch(request)
if results.count > 0 {
for result in results as![NSManagedObject] {
if let username = result.value(forKey: "username") as ? String {
print(username)
}
}
}
else {
print("No results")
}
} catch {
print("Couldn't fetch results")
}
}
}
you can use this too:
let request : NSFetchRequest<Grocery> = Grocery.fetchRequest()
and you get results of the type [Grocery] when you execute the request:
let results : [Grocery] = try manageObjectContext.execute(request)
or
let results = try manageObjectContext.execute(request)
I have a JSON data which I want to map to CoreData when my tableview loaded at first launch.
I found a way to do it in cellForRowAtIndexPath, but this way I can only save the data to CoreData when the cell is displayed.
I want to do it once for all cells.
var yazarMakaleListesi: [JSON]? = []
var authorList = [AuthorList]() // My CoreData
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("YazarCell") as! YazarTableViewCell
cell.yazar = self.yazarMakaleListesi?[indexPath.row]
cell.yazar = self.yazarMakaleListesi?[indexPath.row]
let authorName = self.yazarMakaleListesi?[indexPath.row]["author_name"].string
let authorID = self.yazarMakaleListesi?[indexPath.row]["author_id"].int
let authorImage = self.yazarMakaleListesi?[indexPath.row]["author_image"].string
let newspaperID = self.yazarMakaleListesi?[indexPath.row]["newspaper_id"].string
let newspaperName = self.yazarMakaleListesi?[indexPath.row]["newspaper"].string
let newsPaperImage = self.yazarMakaleListesi?[indexPath.row]["author_image"].string
let articleEntity = NSEntityDescription.entityForName("AuthorList", inManagedObjectContext: self.context!)
let newAuthor = AuthorList(entity: articleEntity!, insertIntoManagedObjectContext: self.context!)
newAuthor.authorName = authorName!
newAuthor.authorImage = authorImage!
newAuthor.newspaperName = newspaperName!
newAuthor.newsPaperImage = newsPaperImage!
newAuthor.authorID = authorID!
var saveError: NSError?
self.context!.save(&saveError)
if let _error = saveError {
println("\(_error.localizedDescription)")
} else {
println("Author Saved!")
}
var error: NSError?
let request = NSFetchRequest(entityName: "AuthorList")
let results = self.context!.executeFetchRequest(request, error: &error) as! [AuthorList]
return cell
}
I get the JSON data here:
func loadYazar(){
if (gazeteid != nil){
let url = "http:myapi.com" + String(gazeteid)
Alamofire.request(.GET, url).responseJSON { (Request, response, json, error) -> Void in
if (json != nil){
var jsonObj = JSON(json!)
if let data = jsonObj["authors"].arrayValue as [JSON]?{
self.yazarMakaleListesi = data
self.tableView.reloadData()
}
}
}
}
}
EDIT : I get my jsonresponse here, implemented # thefredelement's recommendation.
But I get " 'JSON' does not have a member named 'valueForKey'" from line:
newFakeCoreDataObject.authorName = jsonResult.valueForKey("authorName") as! String
Alamofire.request(.GET, url).responseJSON { (Request, response, json, error) -> Void in
if (json != nil){
var jsonObj = JSON(json!)
if let jsonResults = jsonObj["authors"].arrayValue as [JSON]?{
self.yazarMakaleListesi = jsonResults
var error : NSError?
for jsonResult in jsonResults {
let newFakeCoreDataObject = FakeCoreDataObject()
newFakeCoreDataObject.authorName = jsonResult.valueForKey("authorName") as! String
self.context!.save(&error)
}
self.tableView.reloadData()
}
}
I would highly suggest taking that work out of cellForRowAtIndex path and making a separate function that will iterate through your JSON results and save them each, then load the data from core data as a custom object and put that object into an instance array, then use that array for your table data.
Edit: I wouldn't use this code exactly obviously, it's just an example of what I was trying to explain.
import UIKit
import CoreData
class FakeCoreDataObject : NSObject {
// this would really be your NSManagedObject subclass
var authorName = ""
var authorImage = NSData()
var newspaperName = ""
var newspaperImage = NSData()
var authorId = 0 as NSNumber
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var myEntries = [FakeCoreDataObject]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
fetchJson()
prepareTableData()
}
func fetchJson() {
let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDel.managedObjectContext!
var error : NSError?
// Get your json reuslts like you are already
var jsonResults = [AnyObject]() // just for an example
for jsonResult in jsonResults {
let newFakeCoreDataObject = FakeCoreDataObject()
newFakeCoreDataObject.authorName = jsonResult.valueForKey("authorName") as! String
// etc
context.save(&error)
// save whatever else you want for other entities, etc, if you need track out of scope you can do that and then save after the loop
}
}
func prepareTableData() {
let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDel.managedObjectContext!
var error : NSError?
let fetchTableDataRequest = NSFetchRequest(entityName: "whateverItIsCalled")
fetchTableDataRequest.returnsObjectsAsFaults = false
myEntries = context.executeFetchRequest(fetchTableDataRequest, error: &error) as! [FakeCoreDataObject]
// If you need to do this often, reload the table data here too and you can call it from notifications, etc.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myEntries.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// cell stuff you already have but just use the array
// just a tip to set set values to "" or nil if you're creating a big table so you don't get duplciate data while scrolling
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
you should parse the json you receive inside responseJSON:
let jsonObj = NSJSONSerialization.JSONObjectWithData(json, options:NSJSONReadingOptions(rawValue: 0), error: &err) as! NSDictionary
callback(jsonObj as! Dictionary<String, AnyObject>, nil)
var recs:NSArray = jsonObj.objectForKey("authors") as! NSArray
var ct:Int = 0
for item in recs{
var dict:NSDictionary = item as! NSDictionary
// use self.yazarMakaleListesi[ct] here
// process into the dict "author_name" , "author_id", etc
// increment ct
}
self.tableView.reloadData()
How can I have my app run my code every time the app is viewed and not just every time it is opened? Right now I have to exit it, and open it again to run the code.
My app pulls data via JSON and displays it in labels. All of my code is in viewDidLoad.
Is the answer in putting all of the code in viewDidAppear?
Thanks in advance
Here is the whole code:
//
// ViewController.swift
// KitesurfioApp
//
// Created by Lasse Kristensen on 24/10/14.
// Copyright (c) 2014 Lasse Kristensen. All rights reserved.
//
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet weak var labelSpeed: UILabel!
override func viewDidLoad() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "backgroundNotification:", name: UIApplicationWillEnterForegroundNotification, object: nil);
// Set logo in nav bar
navigationItem.titleView = UIImageView(image: UIImage(named: "logo"))
refresh();
}
func backgroundNotification(noftification:NSNotification){
refresh();
println("Refreshed after background")
}
func refresh() {
// Global save values
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
// JSON Fetching
let urlPath = "http://api.openweathermap.org/data/2.5/weather?lat=55.564120&lon=12.568605"
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
dispatch_async(dispatch_get_main_queue(),{
if (error != nil) {
println(error)
}
else {
// Delete old entries in CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
for result in results! {
context.deleteObject(result as NSManagedObject)
context.save(nil)
}
// Start fetching JSON
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var item = jsonResult["wind"] as NSDictionary
var degrees:Float = item["deg"] as Float
var speed:Float = item["speed"] as Float
// Start saving JSON
var newItem = NSEntityDescription.insertNewObjectForEntityForName("WindData", inManagedObjectContext: context) as NSManagedObject
var speedValue:Float = speed as Float
var degreesValue:Float = degrees as Float
newItem.setValue(speedValue, forKey: "speed")
newItem.setValue(degreesValue, forKey: "degrees")
context.save(nil)
}
// Start fetching from CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result in results as [NSManagedObject] {
let degrees:Float = result.valueForKey("degrees")! as Float
let speed:Float = result.valueForKey("speed")! as Float
if speed > 6.0 {
self.labelSpeed.text = "Go kitesurf: \(speed) m/s \(degrees)"
}
else {
self.labelSpeed.text = "Stay in: \(speed) m/s \(degrees)"
}
}
}
else {
println("No data")
}
});
})
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You need to add UIApplicationWillEnterForegroundNotification and refresh your screen there.Put all code from viewDidLoad to helper function like refreh and call it when viewDidLoad or you come in foreground from background or whenever you want to refresh screen.
override func viewDidLoad() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "backgoundNofification:", name: UIApplicationWillEnterForegroundNotification, object: nil);
//put all code of your viewDidLoad to refresh
refresh();
}
func backgoundNofification(noftification:NSNotification){
refresh();
}
func refresh() {
//here is your all code to fetch data and all
}
The following Swift code has to run twice in order to display the JSON data in a label. On the first run the label simply remains blank. It seems to me that the issue could be something along the lines of the JSON part of the code runs last, but I can't figure out why. I have included the code below. I'm still a rookie, so be gentle :D
class ViewController: UIViewController {
#IBOutlet weak var labelDegrees: UILabel!
#IBOutlet weak var labelSpeed: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Set logo in nav bar
navigationItem.titleView = UIImageView(image: UIImage(named: "logo"))
// Global save values
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
// JSON Fetching
let urlPath = "http://api.openweathermap.org/data/2.5/weather?lat=55.564120&lon=12.568605"
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
}
else {
// Delete old entries in CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
for result in results! {
context.deleteObject(result as NSManagedObject)
context.save(nil)
}
// Start fetching JSON
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var item = jsonResult["wind"] as NSDictionary
var degrees:Float = item["deg"] as Float
var speed:Float = item["speed"] as Float
// Start saving JSON
var newItem = NSEntityDescription.insertNewObjectForEntityForName("WindData", inManagedObjectContext: context) as NSManagedObject
var speedValue:Float = speed as Float
var degreesValue:Float = degrees as Float
newItem.setValue(speedValue, forKey: "speed")
newItem.setValue(degreesValue, forKey: "degrees")
context.save(nil)
}
})
task.resume()
// Start fetching from CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result in results as [NSManagedObject] {
let degrees:Float = result.valueForKey("degrees")! as Float
let speed:Float = result.valueForKey("speed")! as Float
if speed > 6.0 {
self.labelDegrees.text = "Go kitesurf: \(speed) m/s"
}
else {
self.labelDegrees.text = "Stay in: \(speed) m/s"
}
}
}
else {
println("No data")
}
}
You are actually fetching the data on another thread with dataTaskWithURL.So you need to write // Start fetching from CoreData code in dataTaskWithURL.As dataTaskWithURL will not immediately executed so // Start fetching from CoreData code will get called first while dataTaskWithURL is fetching the data.So replece the code with below
class ViewController: UIViewController {
#IBOutlet weak var labelDegrees: UILabel!
#IBOutlet weak var labelSpeed: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Set logo in nav bar
navigationItem.titleView = UIImageView(image: UIImage(named: "logo"))
// Global save values
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
// JSON Fetching
let urlPath = "http://api.openweathermap.org/data/2.5/weather?lat=55.564120&lon=12.568605"
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
dispatch_async(dispatch_get_main_queue(),{
if (error != nil) {
println(error)
}
else {
// Delete old entries in CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
for result in results! {
context.deleteObject(result as NSManagedObject)
context.save(nil)
}
// Start fetching JSON
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var item = jsonResult["wind"] as NSDictionary
var degrees:Float = item["deg"] as Float
var speed:Float = item["speed"] as Float
// Start saving JSON
var newItem = NSEntityDescription.insertNewObjectForEntityForName("WindData", inManagedObjectContext: context) as NSManagedObject
var speedValue:Float = speed as Float
var degreesValue:Float = degrees as Float
newItem.setValue(speedValue, forKey: "speed")
newItem.setValue(degreesValue, forKey: "degrees")
context.save(nil)
}
// Start fetching from CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result in results as [NSManagedObject] {
let degrees:Float = result.valueForKey("degrees")! as Float
let speed:Float = result.valueForKey("speed")! as Float
if speed > 6.0 {
self.labelDegrees.text = "Go kitesurf: \(speed) m/s"
}
else {
self.labelDegrees.text = "Stay in: \(speed) m/s"
}
}
}
else {
println("No data")
}
});
})
task.resume()
}