Core Data - Get managed object by URI - objective-c

I'm trying to fetch managed objects from Core Data by their URI. For this I found an Objective-C example of a method (http://www.cocoawithlove.com/2008/08/safely-fetching-nsmanagedobject-by-uri.html) and converted it to Swift ...
func getManagedObjectWithURI(uri:NSURL) -> NSManagedObject?
{
if let psc = persistentStoreCoordinator
{
let objID = psc.managedObjectIDForURIRepresentation(uri);
if (objID != nil)
{
let obj:NSManagedObject = managedObjectContext!.objectWithID(objID!);
if (!obj.fault)
{
return obj;
}
let prd = NSComparisonPredicate(leftExpression: .expressionForEvaluatedObject(), rightExpression: NSExpression(forConstantValue: obj), modifier: .DirectPredicateModifier, type: .EqualToPredicateOperatorType, options: .allZeros);
let req = NSFetchRequest();
req.entity = objID?.entity;
req.predicate = prd;
var results:[NSManagedObject] = managedObjectContext!.executeFetchRequest(req, error: nil) as! [NSManagedObject];
if (!results.isEmpty)
{
return results.first;
}
}
}
return nil;
}
However the method always returns nil, i.e. the fetch request returns empty-handed and I don't know why. Up to the NSFetchRequest everything looks valid. Does anyone has an idea what could be wrong?

Check that the entity and the predicate contain the expected values.
Another suggestion is to write your predicate with NSPredicate(format:) for clarity.
request.predicate = NSPredicate(format: "self = %#", object)
I have changed your variable names for readability.

Solved the issue. It was actually related to another, deeper problem in my core data code explained here: Mac OSX - Core data isn't stored
The above method works fine otherwise.

Related

Passing a tabelview indexPath.row as String to VC WebView

I have a TableViewController which I am attempting to pass through a URL to a WebView on another ViewController
I am overriding the below function, which works find if I make the URL static as you can see in the comment out let newsLink constant
let newsLink = "http://www.stuff.co.nz/business/industries/69108799/Kirkcaldie-Stains-department-store-to-become-David-Jones"
However with the below pulling the URL from indexPath.row it fails for some reason and passes through a nil value
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let newsLink = (posts.objectAtIndex(indexPath.row).valueForKey("link") as! String)
//let newsLink = "http://www.stuff.co.nz/business/industries/69108799/Kirkcaldie-Stains-department-store-to-become-David-Jones"
println(newsLink)
let newsWebViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("idNewsWebViewController") as! NewsWebViewController
newsWebViewController.newsURL = NSURL(string: newsLink)
showDetailViewController(newsWebViewController, sender: self)
}
If I println() the below, I get exactly the same output as the URL I ahve hardcoded in the test let newsLink constant
println(posts.objectAtIndex(indexPath.row).valueForKey("link") as! String)
I can't figure out why this is failing. Hopefully someone smarter than me can help.
The code on the receiving end VC is below"
var newsURL : NSURL!
//var newsURL = NSURL(string: "http://www.google.co.nz")
#IBOutlet weak var newsWebView: UIWebView!
#IBOutlet weak var descTextView: UITextView!
and in the viewDidAppear function
let request : NSURLRequest = NSURLRequest(URL: newsURL!)
newsWebView.loadRequest(request)
More Info
var types
var posts = NSMutableArray()
var elements = NSMutableDictionary()
how I am adding objects
elements.setObject(urlLink, forKey: "link")
posts.addObject(elements)
Could you show the declaration / structure of the "posts" variable?
Without more information, the only thing I can think of is that the value of "link" is not actually a String, but something (maybe a NSURL) that when printed shows that content. That would explain the println showing the same url but the cast failing.
When you print, or implicitly convert any object to a String (as in the println), it calls the "description" method of that object.
For example:
class MyURLContainer {
var link:String
override func description() -> String {
return link
}
}
let url = MyURLContainer()
let url.link = "http://www.example.com"
println( "my link: \(url)" ) // this would show the link correctly
let link = url as? String // this will be nil, as url can't be casted to String
I think (posts.objectAtIndex(indexPath.row).valueForKey("link") does not return a String type. It might already be a NSURL, and hence showing you correct value in println()
Could you post some more details about it. Hope this helped.
It turns out it was the encoding on the URL that NSURL didn't like.
The solution was to use the below:
var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
I'm new to swift, but this seems a bit messy.

CoreData to Array in Swift

I am trying to fetch data from CoreData and return it as an array for charting in a popular charting library. The code below runs fine and I can print the data to the console, however I want to fill self.hkdataBase with the entries within CoreData and Return it. Any idea what I am doing wrong ?
class ViewController: UIViewController {
var hkdataBase = [HKdataBase]()
....
func fetchCoreData () -> NSArray {
//Setting up Core Data
var context = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext!
var request = NSFetchRequest(entityName: "HKdataBase")
request.returnsObjectsAsFaults = false
//Fetching Data
self.hkdataBase = context.executeFetchRequest(request, error: nil)! as [HKdataBase]
if hkdataBase.count > 0 {
for i in hkdataBase {
**I WANT TO FILL self.hkdataBase WITH i ELEMENTS HERE ** -> println(i.hr_data) WORKS FINE
}
} else {
println("No results")
}
}
**return self.hkdataBase with elements**
}
UPDATE 1:
I want to Return an Array from the fetched data in CoreData. The hr_data are Heart Rate measures and hr_date are the associated NSDate. The HKdataBase looks like this:
import Foundation
import CoreData
class HKdataBase: NSManagedObject {
#NSManaged var hr_date: NSDate
#NSManaged var hr_data: NSNumber
}
After the fetch, you already have your managed objects in self.hkdataBase. Managed objects are KVC compliant, so to get just one kind of value out if it is quite simple.
var hrData = (self.hkdataBase as NSArray).valueForKey("hr_data") as NSArray
You now have an array containing your hr_data, presumably an array of NSNumber objects.

How to convert a TStringDynArray to a TStringList

I'm using TDirectory::GetFiles() to get a list of files (obviously).
The result is stored in a TStringDynArray and I want to transfer it to a TStringList for the sole purpose to use the IndexOf() member to see if a string is present in the list or not.
Any solution that will let me know if a certain string is present in the list of files returned from TDirectory::GetFiles() will do fine. Although, it would be interesting to know how to convert the TStringDynArray.
TStringDynArray DynFiles = TDirectory::GetFiles("Foo path");
System::Classes::TStringList *Files = new System::Classes::TStringList;
Files->Assing(DynFiles) // I know this is wrong, but it illustrates what I want to do.
if(Files->IndexOf("Bar") { // <---- This is my goal, to find "Bar" in the list of files.
}
TStringList and TStringDynArray do not know anything about each other, so you will have to copy the strings manually:
TStringDynArray DynFiles = TDirectory::GetFiles("Foo path");
System::Classes::TStringList *Files = new System::Classes::TStringList;
for (int I = DynFiles.Low; I <= DynFiles.High; ++I)
Files->Add(DynFiles[I]);
if (Files->IndexOf("Bar")
{
//...
}
delete Files;
Since you have to manually loop through the array anyway, you can get rid of the TStringList:
TStringDynArray DynFiles = TDirectory::GetFiles("Foo path");
for (int I = DynFiles.Low; I <= DynFiles.High; ++I)
{
if (DynFiles[I] == "Bar")
{
//...
break;
}
}
But, if you are only interested in checking for the existence of a specific file, look at TFile::Exists() instead, or even Sysutils::FileExists().
if (TFile::Exists("Foo path\\Bar"))
{
//...
}
if (FileExists("Foo path\\Bar"))
{
//...
}
* personally, I hate that the IOUtils unit uses dynamic arrays for lists. They are slow, inefficient, and do not integrate well with the rest of the RTL. But that is just my opinion.
TStrings knows TStringDynArray good enough to provide a member AddStrings:
Files->AddStrings(TDirectory::GetFiles("Foo path"));
will do the job.

NSUserDefaults Not Saving TextField Text (Swift)

I'm trying to create a game with Swift, and I want to add the ability to create a username, which will be saved in NSUserDefaults. This is my code:
println("Textfield Text: \(usernameTextfield.text)")
NSUserDefaults.standardUserDefaults().setObject(usernameTextfield.text, forKey:"Username")
NSUserDefaults.standardUserDefaults().synchronize()
println(NSUserDefaults.standardUserDefaults().objectForKey("Username") as? String)
The output is:
Textfield Text: MyUsername
nil
The only explanation I can see as to why it is printing nil is that either the saving or the loading of the username is failing. Is there any way this can be corrected or am I doing something wrong?
Any help is appreciated!
println("Textfield Text: \(usernameTextfield.text)")
var myValue:NSString = usernameTextfield.text
NSUserDefaults.standardUserDefaults().setObject(myValue, forKey:"Username")
NSUserDefaults.standardUserDefaults().synchronize()
var myOutput: AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("Username")
println(myOutput)
In Swift 4.1
UserDefaults.standard.set(textfield.text, forKey: "yourKey") // saves text field text
UserDefaults.standard.synchronize()
// To Retrieve
textfield.text = UserDefaults.standard.value(forKey:"yourKey") as? String
I made a small modification to Roman's answer with Swift 2.0 and Xcode 6.4.
saving:
var myValue:NSString = usernameTF.text
NSUserDefaults.standardUserDefaults().setObject(myValue, forKey:"Username")
NSUserDefaults.standardUserDefaults().synchronize()
retrieving:
var myOutput = NSUserDefaults.standardUserDefaults().objectForKey("Username")
if (myOutput != nil)
{
self.title = "Welcome "+((myOutput) as! String)
}
In Swift 3.0
let userDefult = UserDefaults.standard //returns shared defaults object.
if let userName = usernameTextfield.text {
//storing string in UserDefaults
userDefult.set(userName, forKey: "userName") //Sets the value of the specified default key in the standard application domain.
}
print(userDefult.string(forKey: "userName")!)//Returns the string associated with the specified key.
For swift 3.0, You can create user default by,
UserDefaults.standard.set("yourValue", forKey: "YourString")
To Print the value in console :
print(UserDefaults.standard.string(forKey: "YourString")!)

iOS – Facebook SDK, parsing results

In my -request:didLoad: delegate method I'm NSLoging the results but I can't figure out what's the content?
It looks like result is an NSArray but what is inside it? how do I parse the data?
A sample of the log looks like this:
result: (
{
"fql_result_set" = (
{
uid2 = 1234567;
},
{
uid2 = 12345678;
}
);
name = queryID;
},
{
"fql_result_set" = (
{
"birthday_date" = "05/12/1987";
name = "John Doe";
},
{
"birthday_date" = "03/01/1978";
name = "Jane Doe";
}
);
name = queryBirthday;
}
)
The Facebook iOS tutorial, in "Step 6: Using the Graph API", says
Note that the server response will be in JSON string format. The SDK uses an open source JSON library https://github.com/stig/json-framework/ to parse the result. If a parsing error occurs, the SDK will callback request:didFailWithError: in your delegate.
A successful request will callback request:didLoad: in your delegate. The result passed to your delegate can be an NSArray, if there are multiple results, or an NSDictionary if there is only a single result.
In your example, everything printed by NSLog inside "()" is part of an NSArray, while everything inside "{}" (which also have keys incidentally) is part of an NSDictionary and therefore accessible by key (name).
http://developers.facebook.com/docs/mobile/ios/build/
According to https://developers.facebook.com/docs/reference/api/, all 'responses' are JSON-Objects. To parse these, iOS 5 provides a class called NSJSONSerialization (NSJSONSerialization Class Reference)
You normally parse it as follows:
NSDictionary *dictionaryJSON = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];