how to search for document in an array and delete it? - ios

I am trying to create adding to favorite button, I'am able to add object to an array but for some reason I cannot delete it from the array. How to remove it from the array? .Here is my code. thanks
func didClickFavoriteButton(item: Item) {
// removing from favorite (not working)
if user.favoritCar.contains(item.id!) {
let index = user.favoritCar.firstIndex(of:item.id!)
user.favoritCar.remove(at: index!)
FirebaseReference(.User).document(kFAVORIT).updateData([kFAVORIT :
FieldValue.arrayRemove(user.favoritCar)])
} else {
// Adding to favorite
user.favoritCar.append(item.id!)
FirebaseReference(.User).document(Auth.auth().currentUser!.uid).updateData([kFAVORIT : FieldValue.arrayUnion(user.favoritCar)])
}

Can you try this code:
if let temp = user.favoritCar.first(where: {$0.id == item.id}) {
if let index = user.favoritCar.firstindex(of: temp) {
user.favoritCar.remove(at: index)
}
}
Instead of this code:
if user.favoritCar.contains(item.id!) {
let index = user.favoritCar.firstIndex(of:item.id!)
user.favoritCar.remove(at: index!)

Related

Is there a better way to remove all annotations from PDF document?

I need to remove all annotations from PDF document using PDFKit.
Here is my solution:
This solution doesn't work for me, because in one case im getting exception when mutating array while iteration on it.
func removeAllAnnotations() {
guard let documentCheck = document else { return }
for i in (0..<documentCheck.pageCount) {
if let page = documentCheck.page(at: i) {
for annotation in page.annotations {
page.removeAnnotation(annotation)
}
}
}
}
If you want to avoid the “mutate while iterating” problem, just create your own local copy of the array, and iterate through that:
func removeAllAnnotations() {
guard let document = document else { return }
for i in 0..<document.pageCount {
if let page = document.page(at: i) {
let annotations = page.annotations
for annotation in annotations {
page.removeAnnotation(annotation)
}
}
}
}
But, no, I don’t know of any better way to remove all annotations.
This is the objective-C solution, I came up with. This function will not encounter the “mutate while iterating” crash! Hope this will be helpful to someone.
- (void)removeAllAnnotations {
if (self.pdfDocument) {
for (int i = 0; i < self.pdfDocument.pageCount; i++) {
PDFPage *page = [self.pdfDocument pageAtIndex:i];
PDFAnnotation *annotation = page.annotations.lastObject;
while (annotation) {
[page removeAnnotation:annotation];
annotation = page.annotations.lastObject;
}
}
}
}

Add / Update custom object dictionaries array in swift 4

I have an array of dictionary with custom object in swift.
Now I am comparing the object for add & update.
The logic is as simple to add the data if not exist and update if any change in dictionary.
User is custom object type:
#objc public class User: NSObject , Mappable
from the getUserID i can able to get userID
The below code is execute in for loop from where i am passing User object.
var peopleList = [User]()
if self.peopleList.count > 0 {
if self.peopleList.contains(where: {$0.getUserID() == users.getUserID()})
{
// check for any update in dist
if let index = self.peopleList.index(of: users)
{
if users.isEqual(self.peopleList[index])
{
print("equal no updates")
}
else
{
print("need to updates objects..")
}
}
//already exist room
}
else
{
self.peopleList.append(users)
}
}
I know it may be related to equatable
so I am using below fuction
func isEqual<T: Equatable>(type: T.Type, a: Any, b: Any) -> Bool? {
guard let a = a as? T, let b = b as? T else { return nil }
return a == b
}
But I am getting index = nil.
Is there any idea or suggestion to solve it.
If any other way to do it efficiently them most welcome.
I think this simplified version should work
if self.peopleList.isEmpty, let user = self.peopleList.first(where: { $0.getUserID() == users.getUserID() }) {
if user == users {
// is equal
} else {
// do update
}
} else {
self.peopleList.append(users)
}

Removing CollectionView cell class from array?

I am creating a wizard using UICollectionView with an array of CollectionViewCells:
var viewCells:[BaseCVCell] = [createEventSubjectSearch(), createEventEventForm()]
This array is dynamically added to based on a series of UISwitch's that the user controls. I can add to the array fine using the code below, however I can't seem to remove an item when a user turns the switch off.
func switchToggled(sender : UISwitch) {
if sender == createDiarySwitch {
if sender.isOn {
parentClass?.viewCells.append(createEventDeferEvent())
} else {
if let i = parentClass?.viewCells.index(where: { $0 == createEventDeferEvent() }) {
parentClass?.viewCells.remove(at: i)
}
}
}
if sender == createDeferredSwitch {
if sender.isOn {
parentClass?.viewCells.append(createEventDiariseEvent())
} else {
if let i = parentClass?.viewCells.index(where: { $0 == createEventDiariseEvent() }) {
parentClass?.viewCells.remove(at: i)
}
}
}
parentClass?.wizardCollectionView.reloadData()
}
I have tried the above code, as well as:
if let index = parentClass?.viewCells.index(of: createEventDiariseEvent()) {
parentClass?.viewCells.remove(at: index)
}
Neither approach works (no errors, the code just never returns a value). I'd like to try and avoid naming elements where possible. Is there a way to do this?
Thanks for your answers, DonMag
I've achieved the desired functionality by instanciating the two dynamic cells in the main class:
let diariseCell : createEventDiariseEvent()
and then in the loop calling as thus:
if sender == createDiarySwitch {
if sender.isOn {
parentClass?.viewCells.append((parentClass?.diariseCell)!)
} else {
if let i = parentClass?.viewCells.index(where: { $0 == parentClass?.diariseCell }) {
print("Found cell reference at index \(i)")
parentClass?.viewCells.remove(at: i)
}
}
}
Works a charm now. Amazing what another pair of eyes can pick out!

Get the indexPath of the relevant element in a loop

I'm working in a project in Swift 3.0 and I have a loop that would give me the state of an object (gives a boolean value in a an array sequence). My requirement is if the element state is "true" I wants to get the relevant index path of that, so using that indexPath I can get the whole object from my original array. So inside a loop how can i get that as well? My partially done code is below. In a comment I have stated where I wants to pass this indexPath.
func tapFunction(sender: UIButton) {
// This gives me the selected indexPath
print("ID :",sender.accessibilityIdentifier!)
if let rowIndexString = sender.accessibilityIdentifier, let rowIndex = Int(rowIndexString) {
self.sateOfNewSongArray[rowIndex] = !self.sateOfNewSongArray[rowIndex]
}
sender.isSelected = !sender.isSelected
for (element) in self.sateOfNewSongArray {
//This is where I wants to pass the rowIndex that became true
if element == true {
selectedSongList.addingObjects(from: [songList[rowIndex]])
}
}
}
Note: Make sure your array 'sateOfNewSongArray' has boolean types
of elements
Try following solutions:
Sample Code 1: According to your current code in your question.
func tapFunction(sender: UIButton) {
// This gives me the selected indexPath
print("ID :",sender.accessibilityIdentifier!)
if let rowIndexString = sender.accessibilityIdentifier, let rowIndex = Int(rowIndexString) {
self.sateOfNewSongArray[rowIndex] = !self.sateOfNewSongArray[rowIndex]
}
sender.isSelected = !sender.isSelected
for (index, element) in self.sateOfNewSongArray.enumerated() {
if element {
if let songName:String = songList[index] {
selectedSongList.append(songName)
}
}
}
}
Sample Code 2: More easier and concise.
func tapFunction(sender: UIButton) {
// This gives me the selected indexPath
print("ID :",sender.accessibilityIdentifier!)
if let rowIndexString = sender.accessibilityIdentifier, let rowIndex = Int(rowIndexString) {
if let songName:String = songList[rowIndex] {
selectedSongList.append(songName)
}
}
}
enumerated() is a function, returns sequence of pairs enumerating with index and element of array (by iterating elements of array)
Here is basic sample code, for your understanding. Copy and execute this code:
let songList =  [“cat”, “dog”, “elephant”]
let sateOfNewSongArray = [false, true, false]
let selectedSongList = [String]()
for (index, element) in self.sateOfNewSongArray.enumerated() {
if element {
if let animalName:String = songList[index] {
selectedSongList.append(animalName)
}
}
}
print(“selectedSongList - \(selectedSongList)”)

Proper way to parse with SwiftyJSON

I'm using SwityJSON to iterate through my JSON data and parse it. It's working fine, but I would like to make sure I'm using the syntax correctly and efficiently. Please review my code below:
if let itemDict = json[0]["artists"].dictionaryValue {
for item in itemDict {
if let artist: Dictionary? = item.1.dictionaryValue {
// artist id
if let artistId = artist?["id"] {
if artistId.stringValue != nil {
// add value to object
}
}
// title
if let title = artist?["title"] {
if title.stringValue != nil {
// add value to object
}
}
// subtitle
if let subtitle = artist?["subtitle"] {
if subtitle.stringValue != nil {
// add value to object
}
}
// image url
if let imageURL = artist?["imageURL"] {
if imageURL.stringValue != nil {
// add value to object
}
}
}
}
}
This is new for all but Ray Wenderlich has provided good tutorial. Try to learn from it. It helped me a lot.

Resources