Cannot get the right file to display in UITextView swift - ios

I have declared a global variable 'var recipes = String: PFFile'.
On parse.com, I created a column called "recipe" of type File and i have uploaded .txt files that contain the recipes.
I am trying to load the contents of the .txt files from parse to a UITextView.
I have tried many things and this is what I have:
var recipes = [String: PFFile]()
var valueToPass: String!
var valuePassed: String!
var appetizer = [String]()
var images = [String: UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
let query = PFQuery(className: "Appetizers")
query.orderByAscending("recipe")
query.findObjectsInBackgroundWithBlock { (objects, error) in
guard error == nil, let objects = objects else {
print(error)
return
}
for object in objects {
// ... Appetizer Name
let appetizerName = object.objectForKey("appetizer") as! String
self.name.text = self.valuePassed
// ... Recipe
var recipes = [String: String]()
let recipeFile = object["recipe"] as! PFFile
do {
let recipeData = try recipeFile.getData()
let recipe = String(data: recipeData , encoding:NSUTF8StringEncoding)!
print(recipe) // recipe is now a string you can store or display
self.myTextView.text = recipe
} catch {
print("something went wrong")
}
// ... Image
let imageFile = object["imageFiles"] as!PFFile
imageFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in
if error == nil {
let data = imageData
} else {
print(error)
}
if let data = imageData {
self.images[appetizerName] = UIImage(data: data)
self.imageView.image = self.images[self.valuePassed]
}
})
}
}
}
I am able to display the recipe with the above code but not the one i chose. It is printing all the recipes in the logs but in a random order (but the same order each time) and the last one is the one being printed in the UITextView.
I can't seem to get the one i am choosing.

You create a dictionary recipes of type [string: PFFile]. Presumably this is to contain all the recipes returned by Parse. Then you never populate that dictionary.
Later down in your code you have this line:
let recipeFile = object["recipe"] as! PFFile
Is that the PFFile you want to add to your dictionary?
If so, then you could use code like this:
let someKey = //Whatever string key you want to use to store a recipe
recipes[someKey] = recipeFile
You say "I am trying to load the contents of the .txt files from parse to a UITextView. "
So you're trying to add the combined contents of all the text files into a single UITextView?
In that case you would need to change this line:
let recipe = String(data: recipeData , encoding:NSUTF8StringEncoding)!
Say you create a new var:
var allRecipesText = String()
Then you could add a line below the line that coverts a recipe to a String:
let recipe = String(data: recipeData , encoding:NSUTF8StringEncoding)!
//concatenate the new recipe string to the end of allRecipiesText
allRecipiesText += recipe
Do you really need to save the PFFile objects, or do you want to save the converted text? And do you really want your recipes in a dictionary, or would you rather have them in an array?

With this code, i was able to display the recipe i chose in the previous tableviewcontroller:
let recipeFile = object["recipe"] as! PFFile
do {
let recipeData = try recipeFile.getData()
let recipe = String(data: recipeData , encoding:NSUTF8StringEncoding)!
// recipe is now a string you can store or display
self.recipes[appetizerName] = recipe
self.myTextView.text = self.recipes[self.valuePassed]
} catch {
print("something went wrong")
}
appetizerName: used as the appetizer's name
valuePassed: chosen recipe in the tableview controller

Related

separate json content that separated by a comma

I am parsing json data in swift 3. this is the structure of the result.
I need to separate this brackected content and put them into a array.
(
{
name:"devin,patrick";
}
,
{
name:"devin,kalvin";
}
,
{
name: "devin,nic";
}
)
This is the code,
//parsing json data
if let jsonparsed = content as? NSDictionary {
if let neededData = jsonparsed["data"] {
print(neededData)
let exactData = String(describing:neededData)
let gotData = exactData.components(separatedBy: ",")
}
}
I converted data to a string and tried to separate content by comma, it wont work because name also having commas, I need to separate content that covered by comma, Any help would be great.
After serializing your json string, get a list of Dictionary, get the name of each dictionary and then do the componentsSeparatedBy yo get every name
if let data = text.data(using: .utf8) ,
let dict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: String]{
let array = dict.flatMap({$0["name"]}) //return ["devin,patrick", "devin,kalvin", "devin,nic"]
let names = array.flatMap({$0.components(separatedBy: ",")}) //return ["devin" ,"patrick" ,"devin" ,"kalvin" ,"devin" ,"nic"]
let uniqueNames = Set(names) // return ["nic", "patrick", "devin", "kalvin"]
}

swift 3.1 reading CSV or PLIST file from web

I'd like to use readStringFromURL method to obtain a file from a plist and then use it on insertDataInArrayFromPlist in order to display it or put it on CoreData, substituting let path = Bundle.main.path(forResource: plistFileName, ofType: plistFileExtension).
the ISSUE the try statement gives me this ERROR
Argument labels '(contentsOfURL:, usedEncoding:)' do not match any available overloads
in my viewDidLoad:
let obtainedfile = readStringFromURL(stringURL: kremoteSamplePlist)
print(obtainedfile ?? "nothing to print")
I retrive the file from web
func readStringFromURL(stringURL:String)-> String!{
if let url = NSURL(string: stringURL) {
do {
return try String(contentsOfURL: url, usedEncoding: nil)
} catch {
print("Cannot load contents")
return nil
}
} else {
print("String was not a URL")
return nil
}
}
then I put the data in a struct
func insertDataInArrayFromPlist(arrayOfEntities: inout [product]) {
let path = Bundle.main.path(forResource: plistFileName, ofType: plistFileExtension)
let localArray = NSArray(contentsOfFile: path!)!
for dict in localArray {
var futureEntity = product()
let bdict = dict as! [String: AnyObject]
futureEntity.name = bdict["Name"] as? String
futureEntity.ProductId = bdict["Product Id"] as? String
arrayOfEntities.append(futureEntity)
}
for element in arrayOfEntities {
print("name is \(element.name!), the id is \(element.ProductId!)")
}
}
Theres a library available via Cocoapods, CSV.swift by Yaslab. Allows you to import a csv directly in Swift code and convert to a data type of your own. Does the job for me.
https://github.com/yaslab/CSV.swift

Getting image from Core Data

I'm working on a Cocktailapp and want to save my image data to Core Data.
I watched some tutorials and did the same but it's still not working an I don't know why.
I have an Array with all titles for the images:
let imagesAperitif: [String] = ["americano.jpg", "daiquiri.jpg",
"frozen daiquiri.jpg",
"banana frozen daiquiri.jpg", "bronx.jpg", "kir.jpg",
"hugo.jpg", "Manhattann.jpg", "manhattan dry.jpg", "manhattan medium.jpg", "margarita.jpg",
"martini dry.jpg",...
Thats where I call my method for saving the images to Core Data:
setCocktails(nameInsert, zutaten: zutatenInsert, zubereitung: zubereitungInsert, dekoration: dekorationInsert, stil: stilInsert, bild: UIImage(named: imagesAperitif[index])!)
That's a part from the code of saveCocktails method:
let imageData = NSData(data: UIImageJPEGRepresentation(bild, 1.0)!)
eintrag.setValue(imageData, forKey: "bild")
do {
try managedContext.save()
That's part of the fetching method:
let fetchRequest = NSFetchRequest(entityName: "Cocktail")
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
cocktails = results as! [NSManagedObject]
And here I want to get my image back from NSData:
imagesAperitif.append(UIImage(data: eintrag.valueForKey("bild") as! NSData)!)
But the App crashes with this line and I get a "fatal error: unexpectedly found nil while unwrapping an Optional value" error.
Is anybody able to explain this to me because I don't know what to change. Everything I tried went also wrong.
You may want to check nil for eintrag.valueForKey("bild") before case it to NSData
As
func valueForKey(_ key: String) -> AnyObject?
And it's always save to check nil before you append UIImage(data: eintrag.valueForKey("bild") as! NSData)
(I like using guard so here goes :) )
So what I would do here since it looks like the inserting of the NSData object fails:
// We are simultaniously unwrapping objects and checking if objects are nil.
guard let imgAsNSData: NSData = UIImageJPEGRepresentation(bild, 1.0),
let entity: Cocktail = eintrag as? Cocktail else {
// Stop executing the method here, there is no point in going further. Handle any errors here! Either imgAsNSData is nil, or could not cast to your class. A guard statement handles it's errors here.
return
}
// At this point we know we have an NSData object. Assign it to the entity.
entity.bild = imgAsNSData
do {
// Save our entity.
try managedContext.save()
} catch {
// Handle error
}
Fetching:
let fetchRequest = NSFetchRequest(entityName: "Cocktail")
do {
let results: [NSManagedObject] = try managedContext.executeFetchRequest(fetchRequest)
guard let cocktails = results as? [Cocktail] else {
// Could not cast to an array of Cocktail objects.
return
}
// Do stuff with the cocktails object.
Add to your array:
// 1: Check if entity not is nil
// 2: Check if entity's bild property not is nil.
// 3: Check if we can create an image using the NSData
guard let cocktail: Cocktail = eintrag as? Cocktail,
let imgAsNSData: NSData = cocktail.bild,
let image: UIImage = UIImage(data: imgAsNSData) else {
// Required values are nil. Cannot proceed.
return
}
imagesAperitif.append(image)
Untested code so be careful :)

Trouble on plist file using swift

I have two variable called "Countries" and "Places" and I'm trying to read a Data.plist and retrieve some values
This is the Data.plist:
Data.plist
I can't read the plist from the variables.
Let use as an example, the value of Countries is "Italia" and the value of Places is "Naples", how can I retrieve the two different values written in "Item 0" and "Item 1".
I've been searching for days in internet some tutorial who could help me but I couldn't make any of these working for my case (I used more tutorial examples but due my low reputation I can't post more than 2 links).
I tried to follow these tutorial:
Swift - searching through dictionaries in an array in a plist
http://sweettutos.com/2015/06/03/swift-how-to-read-and-write-into-plist-files/
I tried, for example, to use this code without use the "variables", but even this is not working:
let path = NSBundle.mainBundle().pathForResource("Dati", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)
let value: AnyObject = (dict!.objectForKey("Italia")!.objectForKey("Naples")?.objectForKey("Item 0"))!
Can you please help me on this?
Thanks in advance.
This is a pure Swift solution using only Swift native types:
if let url = NSBundle.mainBundle().URLForResource("Dati", withExtension: "plist"), data = NSData(contentsOfURL: url) {
do {
let dictionary = try NSPropertyListSerialization.propertyListWithData(data, options: [], format: nil) as! [String:AnyObject]
if let city = dictionary["Italia"]?["Naples"] as? [AnyObject] {
let item0 = city[0] as! Int
let item1 = city[1] as! String
} else {
print("Italia or Naples doesn't exist")
}
} catch let error as NSError {
print("Property List Serialization Error: \(error)")
}
} else {
fatalError("File couldn't be read")
}
If you change the plist file to use only String values you can avoid some type casting
if let url = NSBundle.mainBundle().URLForResource("Dati", withExtension: "plist"), data = NSData(contentsOfURL: url) {
do {
let dictionary = try NSPropertyListSerialization.propertyListWithData(data, options: [], format: nil) as! [String:[String:[String]]]
if let city = dictionary["Italia"]?["Naples"] {
let item0 = city[0]
let item1 = city[1]
} else {
print("Italia or Naples doesn't exist")
}
} catch let error as NSError {
print("Property List Serialization Error: \(error)")
}
} else {
fatalError("File couldn't be read")
}

Display array after action

I have a little app that downloads some names from the web, and then appends them to an array.
func fetchTitle(identifier: String, completion: (title: String) -> Void) {
let profileUrl = NSURL(string:"http://www.facebook.com/" + identifier)!
let task = NSURLSession.sharedSession().dataTaskWithURL(profileUrl) {
(data, response, error) -> Void in
if let urlContent = data {
let webContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding)
let websiteArray = webContent!.componentsSeparatedByString("pageTitle\">")
let secondArray = websiteArray[1].componentsSeparatedByString("</title>")
let title = secondArray[0]
completion(title: title)
print(title)
}
}
task.resume()
}
//print(newArray)
var titles = [String]()
//let identifiers = ["100001986741004","100003866283798","100003455181526"]
let queue = dispatch_queue_create("titles", DISPATCH_QUEUE_SERIAL)
dispatch_apply(newArray.count, queue) { index in
let identifier = newArray[index]
fetchTitle(identifier) { title in
dispatch_async(queue) {
titles.append(title)
array.append(title)
}
}
}
I know it's pretty complicated, because it takes numbers from an array and turns them into names downloaded from the web, but never mind about that. The problem is, when I print title, it gives me the names, so I assume it does append them to the array, but when I print the array, it gives me no result.. I think this is because it takes a little while to download the data from the web, and the print happens immediately, but how to I delay the print (or display into table view) until the download is complete?
Any help is appreciated!
Thank you very much!
I don't know about swift, but when your data has been retrieved, in Objective-C you can call [tableView reloadData]; should be simple enough to translate to Swift

Resources