use textFieldDidEndEditing textfield delegate to find 3 element in array - arrays

My swift code below uses UITextFieldDelegate in textfield var enterT. nameString converts a core data entity to the array of strings, like [bob,bryan,jessica]. In textFieldDidEndEditing, I want the user to be able to enter any number, e.g 3 and third element from the array to be printed and then sort the array.
import UIKit
import CoreData
class ViewController: UIViewController,UITextFieldDelegate {
#IBOutlet var labelName : UILabel!
#IBOutlet var enterT : UITextField!
let appDelegate = UIApplication.shared.delegate as! AppDelegate //Singlton instance
var context:NSManagedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
openDatabse()
}
func textFieldDidEndEditing(_ textField: UITextField) {
guard let index = Int(textField.text!) else {
// display an alert about invalid text
return
}
joke(at: index)
}
func joke(at index : Int) {
let fetchRequest = NSFetchRequest<Users>(entityName: "Users")
fetchRequest.predicate = NSPredicate(format: "idx == %d", Int32(index))
do {
if let user = try context.fetch(fetchRequest).first {
print(user.username)
}
} catch {
print("Could not fetch \(error) ")
}
}
func openDatabse()
{
context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Users", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
let newUser2 = NSManagedObject(entity: entity!, insertInto: context)
let newUser3 = NSManagedObject(entity: entity!, insertInto: context)
saveData(UserDBObj: newUser, UserDBObj2: newUser2, UserDBObj3: newUser3)
}
func saveData(UserDBObj:NSManagedObject,UserDBObj2:NSManagedObject,UserDBObj3:NSManagedObject)
{
UserDBObj.setValue("kim kardashian", forKey: "username")
UserDBObj2.setValue("jessica biel", forKey: "username")
UserDBObj3.setValue("Hailey Rienhart", forKey: "username")
print("Storing Data..")
do {
try context.save()
} catch {
print("Storing data Failed")
}
fetchData()
}
func fetchData()
{
print("Fetching Data..")
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
let userName = data.value(forKey: "username") as! String
print("User Name is : "+userName)
}
} catch {
print("Fetching data Failed")
}
}}

Convert the entered number to Int. If this succeeds pass the integer to joke and fetch the record matching the idx attribute.
Consider that indexes start with zero. If you want to enter numbers starting with one you have to decrement the index (joke(at: index - 1))
#IBOutlet var enterT : UITextField!
func textFieldDidEndEditing(_ textField: UITextField) {
guard let index = Int(textField.text!) else {
// display an alert about invalid text
return
}
joke(at: index)
}
func joke(at index : Int) {
let fetchRequest = NSFetchRequest<Users>(entityName: "Users")
fetchRequest.predicate = NSPredicate(format: "idx == %d", Int32(index))
do {
if let user = try context.fetch(fetchRequest).first {
print(user.username)
}
} catch {
print("Could not fetch \(error) ")
}
}
Note: I recommend to define idx and username as non-optional in the Core Data model. And make sure that all idx values are unique.

Related

Array value shows all information of the coreData value rather than just the value

I'm hoping someone can help me understand how to get the value from an array rather than all system information about the array as shown via screen shot below.
I would instead prefer just "test" to show to prove that CoreData saved and returned the value.
Here is the code:
import UIKit
import CoreData
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let newItem = Item(context: context)
var textIn = ""
var textOut = ""
var itemArray = [] as Array
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBOutlet weak var dataIn: UITextField!
#IBAction func save(_ sender: Any) {
newItem.title = dataIn.text
saveItems()
}
#IBOutlet weak var textLabel: UILabel!
#IBAction func showButton(_ sender: Any) {
loadItems()
}
func saveItems() {
do {
try context.save()
print("Saved!")
} catch {
print("Error saving context \(error)")
}
}
func loadItems() {
let request : NSFetchRequest<Item> = Item.fetchRequest()
do {
itemArray = try context.fetch(request) as [Any]
for item in itemArray {
print(item.self)
textLabel.text = ("Value: \(item.self)")
}
} catch {
print("Error fetching data from context \(error)")
}
}
}
Thanks!
Rather than the worst type [Any] use the best type [Item]
var itemArray = [Item]()
Then remove the pointless type cast in loadItems to be able to use the title attribute
func loadItems() {
let request : NSFetchRequest<Item> = Item.fetchRequest()
do {
itemArray = try context.fetch(request)
for item in itemArray {
print(item.title)
textLabel.text = ("Value:", item.title)
}
} catch {
print("Error fetching data from context \(error)")
}
}
Consider that after the loop the label will display always the title of the last item in the array.

array return empty when call it out of own method

i am making a url call with alamofire to GET data as below . when i print variables inside the call method its show correctly but when i call that out side the method , like View dIdLoad or some where there no value inside array and print empty [ ] .
class ChartVC: UIViewController {
var _year : [String] = []
var _month : [String] = []
var _price : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
getData()
// show empty array
print(_month)
}
func getData() {
AF.request(DOLLAR_CHART).response { (response) in
guard let data = response.data else { return }
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let items = responseJSON as? [[String: Any]] {
var years: [String] = []
var months: [String] = []
var prices: [String] = []
for item in items {
if let year = item["year"] as? String {
years.append(year)
}
if let month = item["month"] as? String {
months.append(month)
}
if let price = item["price"] as? String{
prices.append(price)
}
}
self._year = years
self._month = months
self._price = prices
//print correctly
print(_months)
} else {
print("json is not array dictionary")
}
}
}
You are adding data after the network calls completed. It will print data everytime once your call is completed. At the time of did load the initial data (which is empty intialization in your case) will be printed.
If you want to do any UI updates then do updtae after your call is completed.
This is because the request takes a while to receive the answer, and your print(_month) in the viewDidLoad() method is executed before the answer from the service.
You need to wait for the service to return, parse the response and only then use the data.
A good approach would be this:
self._year = years
self._month = months
self._price = prices
//print correctly
self.updateUI()
func updateUI() {
//Use response
}
EDIT - Full code
class ChartVC: UIViewController {
var _year : [String] = []
var _month : [String] = []
var _price : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
getData()
}
func getData() {
AF.request(DOLLAR_CHART).response { (response) in
guard let data = response.data else { return }
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let items = responseJSON as? [[String: Any]] {
var years: [String] = []
var months: [String] = []
var prices: [String] = []
for item in items {
if let year = item["year"] as? String {
years.append(year)
}
if let month = item["month"] as? String {
months.append(month)
}
if let price = item["price"] as? String{
prices.append(price)
}
}
self._year = years
self._month = months
self._price = prices
self.updateUI()
} else {
print("json is not array dictionary")
}
}
}
func updateUI() {
//USE THE RESPONSE AND UPDATE THE UI HERE
}

Pass an arrays row shown in an NSTableView to another array in Swift

I have 2 arrays
var messages = [Message]()
var screenMessages = [screenMessage]()
I have the messages array items in a NSTableView.. when I press an IBOutlet I would like to pass the items in that row to the screenMessages array to present in another NSTableView.
My NSTableView starts like so..
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let result = tableView.makeViewWithIdentifier("cell", owner: self) as? secondviewTableCell
let mess = messages[row]
I've tried a number of ways of appending the screenMessages with the messages[row] but I can't put my finger on it. If anyone could demonstrate or point me in the right direction that would be brilliant.
Thank you.
Added more detail:
Screen one looks like so and when pressing the add button it should then pass that data from that row into screen twos tableview..
Screen two:
My View for screen one is as:
import Firebase
import Cocoa
var messages = [Message]()
var screenMessages = [screenMessage]()
class secondVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
#IBOutlet weak var tableView: NSTableView!
#IBOutlet weak var screenRefreshBtn: NSButton!
#IBOutlet weak var refreshButton: NSButton!
var senderImageUrl: String!
var ref: Firebase!
var messagesRef: Firebase!
func setupFirebase() {
messagesRef = Firebase(url: "https://url.firebaseio.com/screenmessages")
messagesRef.queryLimitedToLast(25).observeEventType(FEventType.ChildAdded, withBlock: { (snapshot) in
let text = snapshot.value["text"] as? String
let sender = snapshot.value["senderName"] as? String
let imageUrl = snapshot.value["profileImageURL"] as? String
let MediaType = snapshot.value["MediaType"] as! String
let fileUrl = snapshot.value["fileUrl"] as? String
let message = Message(text: text, sender: sender, imageUrl: imageUrl, MediaType: MediaType, fileUrl: fileUrl)
messages.append(message)
let screenmessage = screenMessage(text: text, sender: sender, imageUrl: imageUrl, MediaType: MediaType, fileUrl: fileUrl)
screenMessages.append(screenmessage)
switch MediaType{
case "TEXT":
print("text message")
case "PHOTO":
print("photo message")
default:
print("default")
}
self.tableView.reloadData()
})
}
override func viewDidLoad() {
super.viewDidLoad()
setupFirebase()
}
// MARK: - Table View
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return messages.count
}
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let result = tableView.makeViewWithIdentifier("cell", owner: self) as? secondviewTableCell
let mess = messages[row]
if mess.text() == nil {
result?.textField?.alphaValue = 0
result!.sendertextView.stringValue = mess.sender()
let url = NSURL(string: mess.fileUrl()!)!
// Download task:
// - sharedSession = global NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage objects.
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
// if responseData is not null...
if let data = responseData{
// execute in UI thread
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let photo = NSImage(data: data)!
result?.mediaPhoto.image = photo
})
}
}
task.resume()
} else {
result!.textField!.stringValue = mess.text()!
result!.sendertextView.stringValue = mess.sender()
}
return result
}
#IBAction func addtablerow(object: NSButton) {
let row = tableView.rowForView( object as NSView )
if ( row > -1 ) {
}
}
And my second screen is:
import Cocoa
class screenVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
var addedObserver = false
#IBOutlet weak var tableView: NSTableView!
override func viewDidLoad() {
super.viewDidLoad()
refreshObs()
clearObs()
self.tableView.backgroundColor = NSColor.clearColor()
if let window = self.view.window {
// custom window here
window.level = Int(CGWindowLevelForKey(.FloatingWindowLevelKey))
} else {
addedObserver = true
self.addObserver(self, forKeyPath: "view.window", options: [.New, .Initial], context: nil)
}
}
func refreshList(notification: NSNotification){
self.tableView.alphaValue = 0
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
animateViewRefresh()
tableView.scrollToEndOfDocument(self)
}
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return screenMessages.count
}
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
let result = tableView.makeViewWithIdentifier("cell2", owner: self) as? screenviewTableCell
let mess = screenMessages[row]
result?.senderLabel.stringValue = mess.sender()
if mess.text() != nil {
result?.messageTextView.stringValue = mess.text()!
let url = NSURL(string: mess.imageUrl()!)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
if let data = responseData{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
result?.avatarImage.image = NSImage(data: data)
})
}}
task.resume()
} else {
result?.messageTextView.alphaValue = 0
let mess = screenMessages[row]
let url = NSURL(string: mess.fileUrl()!)!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
if let data = responseData{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let photo = NSImage(data: data)!
result?.mediaPhoto.image = photo
})
}
}
let url2 = NSURL(string: mess.imageUrl()!)!
let task2 = NSURLSession.sharedSession().dataTaskWithURL(url2) { (responseData, responseUrl, error) -> Void in
if let data = responseData{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
result?.avatarImage.image = NSImage(data: data)
})
}}
task.resume()
task2.resume()
}
return result
}
// MARK : Animate
func animateView(notification: NSNotification){
NSAnimationContext.runAnimationGroup({ (context) in
context.duration = 2
self.tableView.animator().alphaValue = 0
screenMessages.removeAll()
}, completionHandler: { () -> Void in
})}
func animateViewRefresh(){
NSAnimationContext.runAnimationGroup({ (context) in
context.duration = 4
self.tableView.animator().alphaValue = 1
}, completionHandler: { () -> Void in
})}
func refreshObs(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(screenVC.refreshList(_:)), name:"refreshMyTableView", object: nil)
}
func clearObs(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(screenVC.animateView(_:)), name:"clearMyTableView", object: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if let window = self.view.window {
// custom window here
window.level = Int(CGWindowLevelForKey(.FloatingWindowLevelKey))
window.titlebarAppearsTransparent = true
window.movableByWindowBackground = true
window.opaque = true
window.backgroundColor = NSColor.clearColor()
}
}
deinit {
if addedObserver {
self.removeObserver(self, forKeyPath: "view.window")
}
}
}
I have tried a number of things such as 'screenMessages += messages(row)' and appending to add that row to the screenMessages array but I've had no luck.
Am I going about this in the right way or is there a better way of doing so?
Thank you.
To append an element from one array to another array just write
let index = index of element you need
let message = messages[index]
screenMessages.append(message)
If message is not the same type as the contents of the screenMessages array you will need to convert it, I would need more details of the types to help with that.
If you are having trouble passing the data to another ViewController I would need more information on the current architecture to give good advice, but for example you might define a protocol MessageDelegate that one of the controllers implements and the other has as a property.
update
If you update your data array for a table and want the new information to appear remember to call reloadData on the UITableView

How to loop data in JSON When string in label equal data in JSON array

I need to show data from JSON on label. But my code get error.please help me see on function barcodeReaded. How to loop data when String in label equal string in "testCode" on array JSON file.
This JSON file
{
"episode": [
{
"testCode": "11111111",
"title": "Stomachic mixture 180 ml",
"drug": "AAAAA",
"thumbnailURL": "https://firebasestorage.googleapis.com/v0/b/rxscan-a14ee.appspot.com/o/j01.jpg?alt=media&token=5718797b-fc9c-416e-9394-b544c2880dc9",
"price": "100"
},
{
"testCode": "22222222",
"title": "Parasetamol 200 ml",
"drug": "BBBBB",
"thumbnailURL": "urlImage",
"price": "150"
},
{
"testCode": "33333333",
"title": "Beramol 300 ml",
"drug": "CCCCC",
"thumbnailURL": "urlImage",
"price": "120"
}
]
}
This some code
import UIKit
class barcodeViewController: UIViewController, BarcodeDelegate {
#IBOutlet weak var thumbnailImageView: UIImageView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var drugLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var showCodeLabel: UILabel!
var episode: Episode!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
print("Segue!")
let barcodeViewController: barcodeCapViewController = segue.destinationViewController as! barcodeCapViewController
barcodeViewController.delegate = self
}
#IBAction func doneButtonPressed(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func barcodeReaded(barcode: String) {
print("Barcode is: \(barcode)")
showCodeLabel.text = barcode
barcode = episode.testCode
if((episode.testCode) != nil)
{
titleLabel.text = episode.title
drugLabel.text = episode.drug
priceLabel.text = episode.price
}
}
}
import Foundation
class Episode
{
var title: String?
var thumbnailURL: NSURL?
var drug: String?
var price: String?
var testCode: String?
init(title: String, thumbnailURL: NSURL, drug: String, price: String, testCode: String)
{
self.title = title
self.thumbnailURL = thumbnailURL
self.drug = drug
self.price = price
self.testCode = testCode
}
typealias EpisodeDictionary = [String : AnyObject]
init(espDictionary: EpisodeDictionary)
{
self.title = espDictionary["title"] as? String
self.thumbnailURL = NSURL(string: espDictionary["thumbnailURL"] as! String)
self.drug = espDictionary["drug"] as? String
self.price = espDictionary["price"] as? String
self.testCode = espDictionary["testCode"] as? String
}
static func downloadAllEpisodes() -> [Episode]
{
var episodes = [Episode]()
let jsonFile = NSBundle.mainBundle().pathForResource("testJson3edit6", ofType: "json")
let jsonData = NSData(contentsOfFile: jsonFile!)
if let jsonDictionary = NetworkService.parseJSONFromData(jsonData) {
let espDictionaries = jsonDictionary["episodes"] as! [EpisodeDictionary]
for dict in espDictionaries {
let episode = Episode(espDictionary: dict)
episodes.append(episode)
}
}
return episodes
}
}
NetworkService.swift
import Foundation
class NetworkService
{
// TODO: Make this class be able to download images from a URL
lazy var configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
lazy var session: NSURLSession = NSURLSession(configuration: self.configuration)
let url: NSURL
init(url: NSURL)
{
self.url = url
}
func downloadImage(completion: (NSData -> Void))
{
let request = NSURLRequest(URL: self.url)
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) in
if error == nil {
if let httpResponse = response as? NSHTTPURLResponse {
switch (httpResponse.statusCode) {
case 200:
if let data = data {
completion(data)
}
default:
print(httpResponse.statusCode)
}
}
} else {
print("Error download data: \(error?.localizedDescription)")
}
}
dataTask.resume()
}
}
extension NetworkService
{
static func parseJSONFromData(jsonData: NSData?) -> [String : AnyObject]?
{
if let data = jsonData {
do {
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as? [String : AnyObject]
return jsonDictionary
} catch let error as NSError {
print("Error processing json data: \(error.localizedDescription)")
}
}
return nil
}
}
This code for get image that use in detailViewController
if episode.thumbnailURL != nil {
if let thumbnailURL = episode.thumbnailURL {
let networkService = NetworkService(url: thumbnailURL)
networkService.downloadImage({ (data) in
//thumbnailImageView.image = episode.thumbnailURL
let image = UIImage(data: data)
dispatch_async(dispatch_get_main_queue(), {
self.thumbnailImageView.image = image
})
})
}
}
You can get detail of your barcode like this from your array of dictionary.
func barcodeReaded(barcode: String) {
print("Barcode is: \(barcode)")
showCodeLabel.text = barcode
let episodes = Episode.downloadAllEpisodes()
var filteredEpisodes = episodes.filter({ $0.testCode == barcode })
if filteredEpisodes.count > 0 {
titleLabel.text = filteredEpisodes[0].title
drugLabel.text = filteredEpisodes[0].drug
priceLabel.text = filteredEpisodes[0].price
}
}
Try it. Hope it may help you.
var resultData = NSDictionary()
var episode = NSArray()
func loadDataFromJSON(){
// put your json to resultData
// Now resultData holds whole json object
// get episode array from resultData
episode = resultData.objectForKey("episode") as! NSArray
}
func traverseThroughEpisode(){
for i in 0..< episode.count {
// retrive testCode like that & set it whatever you want
let testCode = episode.objectAtIndex(i).objectForKey("testCode") as! String
}
}

How to check equality of object properties in an array of objects. Swift

I have a class called Movie, which as of now, only has a string property called movieTitle.
I have an array of Movie, and using the .contains method returns false even when an object with the same title is in the array. Interestingly enough, .contains works in a playground I made but not in an app setting.
Thanks for the help! I'm fairly new to the programing game so if you and ELI5 things, that would be great!
Here's a snippet of the code I have. What ends up happening, is it just keeps adding the same 10 entries onto the array.
do{
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String: AnyObject]
if let movieSearch = json["Search"] as? [[String: AnyObject]] {
for movie in movieSearch {
if let title = movie["Title"] as? String {
let newMovie = Movie(movieTitle: title)!
if (!self.movieList.contains(newMovie)) {
self.movieList.append(newMovie)
}
self.tableView.reloadData()
}
}
}
}catch {
print("Error with Json: \(error)")
}
Movie Class
import UIKit
class Movie: NSObject, NSCoding {
// MARK: Properties
struct PropertyKey {
static let movieTitleKey = "title"
}
// MARK: Archiving Paths
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("Movies")
var movieTitle: String
// MARK: Initialization
init?(movieTitle: String) {
// Initialize stored properties.
self.movieTitle = movieTitle
super.init()
// Initialization should fail if there is no itemName
if movieTitle.isEmpty {
return nil
}
}
// MARK: NSCoding
func encode(with aCoder: NSCoder) {
aCoder.encode(movieTitle, forKey: PropertyKey.movieTitleKey)
}
required convenience init?(coder aDecoder: NSCoder) {
let title = aDecoder.decodeObject(forKey: PropertyKey.movieTitleKey) as! String
//Must call designated initializer.
self.init(movieTitle: title)
}
}
// MARK: Equatable
func ==(lhs: Movie, rhs: Movie) -> Bool { // Implement Equatable
return lhs.movieTitle == rhs.movieTitle
}
What works in playgrounds
class Movie: NSObject {
var movieTitle: String
init?(movieTitle: String) {
// Initialize stored properties.
self.movieTitle = movieTitle
super.init()
// Initialization should fail if there is no itemName
if movieTitle.isEmpty {
return nil
}
}
}
var movieList = [Movie]()
var movie1 = Movie(movieTitle: "Batman")
var movie2 = Movie(movieTitle: "Batman")
var movie3 = Movie(movieTitle: "Superman")
movieList.append(movie1!)
movieList.append(movie2!)
movieList.contains(movie1!) // Returns True
movieList.contains(movie3!) // Returns False
Because your Movie class (why is it a class?) inherits from NSObject (why?), it inherits NSObject's conformance of the Equatable protocol, with the NSObject implementation of ==. By default, this does identity comparison (comparing references), rather than value comparison.
Here's an example:
let movie1 = Movie(movieTitle: "Batman")
let movie2 = Movie(movieTitle: "Batman")
var movieList = [Movie1]
movieList.contains(movie1!) // True, because movie1 was added in
movieList.contains(movie2!) // False, movie2 was never added
Since Movie doesn't override == with an implementation that compares its value(s) (such as movieTitle), it defers to the default implementation, which is comparing the references. Even though movie2 has the same value, it's a distinct object with its own (separate) memory location. Thus, the identity comparison fails, and it's not found.
To solve this implement == to return true iff all the fields of Movie match up. What you're trying to do may be better off being implemented with structs, however.
you should try with this way.
var filtered = [Movie]()
filtered = movieList.filter({$0.movieTitle == "Superman"})
if filtered.count == 1 {
//so,"Superman" movie contained in array..
}
let me know the results... thanks.
Just try this code it works perfectly.
do{
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String: AnyObject]
if let movieSearch = json["Search"] as? [[String: AnyObject]] {
for movie in movieSearch {
if let title = movie["Title"] as? String {
let newMovie = Movie(movieTitle: title)!
let movieTitles = (self.movieList as NSArray).value(forKeyPath: "movieTitle") as? [String]
if movieTitles == nil || movieTitles!.contains(title) == false {
self.movieList.append(newMovie)
}
self.tableView.reloadData()
}
}
}
}catch {
print("Error with Json: \(error)")
}
Try overriding isEqual method of NSObject since it is already conforming Equatable protocol. You can test the code below in a playground. Hope it helps.
class Movie: NSObject {
var movieTitle: String
init?(movieTitle: String) {
// Initialize stored properties.
self.movieTitle = movieTitle
super.init()
// Initialization should fail if there is no itemName
if movieTitle.isEmpty {
return nil
}
}
override func isEqual(_ object: Any?) -> Bool {
guard let theMovie = (object as? Movie) else { return false }
return movieTitle == theMovie.movieTitle
}
}
var movieList = [Movie]()
func appendToList(newMovie: Movie) {
if (!movieList.contains(newMovie)) {
movieList.append(newMovie)
}
}
var movie1 = Movie(movieTitle: "Batman")
var movie2 = Movie(movieTitle: "Batman")
var movie3 = Movie(movieTitle: "Superman")
appendToList(newMovie: movie1!)
movieList.count // count is 1
appendToList(newMovie: movie2!)
movieList.count // count is still 1 not incremented
movieList.contains(movie1!) // Returns true
movieList.contains(movie2!) // Returns true
movieList.contains(movie3!) // Returns false

Resources