포스트

Todoey (8)

Query 작성하기.

지금 Query에 해당하는 부분은 SearchBar에 대한 부분 밖에 없다.

그 부분의 내용을 고쳐보도록 하자.

todoItems = todoItems?.filter(<#T##predicateFormat: String##String#>, <#T##args: Any...##Any#>) 에서 필터를 사용한 것을 다시 todoitems에 담는다.

predicateFormat에는 NSpredicateFormat과 동일하게 작성한다.

즉, "title CONTAINS[cd] %@" 이 부분이 그대로 들어간다는 뜻

todoItems = todoItems?.filter("title CONTAINS[cd] %@", searchBar.text!) 이렇게 된다.

NSpredicate사용했을때와 비교하면 let predicate = NSPredicate(format: "title CONTAINS[cd] %@", searchBar.text!)

내용은 같다.

하지만 이전에는 필터링한 결과를 가지고 소팅을 했다면 이번엔 바로 소팅 메서드를 연결할 수 있다.

todoItems = todoItems?.filter("title CONTAINS[cd] %@", searchBar.text!).sorted(byKeyPath: "title", ascending: true)

이전에 길었던 코드가 한줄로 해결이 되는 매직이 발생했다.

1. 날짜를 기준으로 소팅해보기

@objc dynamic var dateCreated: Date? 생성

newItem.dateCreated = Date() 도 추가.

1
2
3
error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=10 "Migration is required due to the following errors:
- Property 'Item.dateCreated' has been added." UserInfo={Error Name=SchemaMismatch, NSLocalizedDescription=Migration is required due to the following errors:
- Property 'Item.dateCreated' has been added., Error Code=10}

다음과 같은 에러가 뜬다.

CleanShot 2024-04-15 at 17 11 24@2x

현재 DB에는 dateCreated라는 속성이 없기에 발생한 문제!

즉 에러에서 말하는 그대로 Migration이 필요하다는 것이다.

2. Migration 하기

simulator_screenshot_AE547643-C9D3-44F4-BB0C-96CC3EF5307C

앱을 삭제하자!

즉 새로운 Realm파일로 시작하는 의미.

CleanShot 2024-04-15 at 17 15 14@2x

새로 생긴걸 알 수 있다.

CleanShot 2024-04-15 at 17 16 22@2x

값을 추가하니 date가 잘 나오는걸 알 수 있다.

Swipe하여 삭제기능 구현

CocoaPod의 라이브러리를 사용할것이다.

사이트에 정보가 나와있다.

예시를 바탕으로 코드 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// sample
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! SwipeTableViewCell
        cell.delegate = self
        return cell
    }
// modified
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell") as! SwipeTableViewCell
        
        cell.textLabel?.text = categories?[indexPath.row].name ?? "No Categories added Yet"
        cell.delegate = self
        
        return cell
    }

1. extension을 사용하여 코드 확장

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
extension CategoryViewController: SwipeTableViewCellDelegate {
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
        guard orientation == .right else { return nil } // swipe 방향

        let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
            // handle action by updating model with deletion
        }

        // customize the action appearance
        deleteAction.image = UIImage(named: "delete")

        return [deleteAction]
    }
    
}

안의 함수는 현재 readme에 있는 코드내용.

이제 안의 함수부를 수정 할 예정이다.

이미지는 사이트의 이미지를 사용했다.

실행했더니 App Crash가 발생했다.

1
Could not cast value of type 'UITableViewCell' (0x1ec2f2b10) to 'SwipeCellKit.SwipeTableViewCell' (0x101eeeda0).

UITableViewCell을 SwipeCellKit.SwipeTableViewCell로 캐스팅을 할 수 없다고 나왔다.

CleanShot 2024-04-15 at 18 23 59@2x

여기에 Class가 UITableViewCell로 default가 잡혀있는데,

이부분을 바꿔주어야한다.

CleanShot 2024-04-15 at 18 25 15@2x

이렇게 바꿔준다. 모듈도 꼭 확인해보고 체크해두자.

simulator_screenshot_F0D5F0A9-9B4E-4BA1-93C6-F1DFE017DEC2

확인해보니 현재 사이즈가 맞지않는다.

조절을 해야할것같다.

tableView.rowHeight = 85.0 각 셀의 높이를 85으로 주었다.

사진은 업로드 하지않았지만 꽤 괜찮다.

삭제를 하는 코드를 넣어보자.

우선 내 기억대로 해보았는데 에러가 발생했다.

1
2
3
4
5
6
do {
    self.realm.delete(currentCategory)
                    
    } catch {
            print("Error \(error.localizedDescription)")
            }

Exception Error가 발생했다.

내용은 다음과 같다.

1
*** Terminating app due to uncaught exception 'RLMException', reason: 'Can only add, remove, or create objects in a Realm in a write transaction - call beginWriteTransaction on an RLMRealm instance first.'

이전에 작성한걸 보았다.

1
2
3
4
5
6
7
8
do {
    try realm.write {

                    item.done = !item.done
                    }
    } catch {
            print("Error Saving New Items, \(error.localizedDescription)")
            }

realm.write를 빼먹었다.

분명히 기억에 try도 썼는데 어디갔나 했다.

잘 기억해두자.

1
2
3
4
5
6
7
8
9
10
11
if let currentCategory = self.categories?[indexPath.row] {
                do {
                    try self.realm.write {
                        self.realm.delete(currentCategory)
                    }
                } catch {
                    print("Error \(error.localizedDescription)")
                }
                tableView.reloadData() // new
            }
           

reloadData를 안하니 에러가 발생했다.

문제를 바로 확인하고 추가하니 작동이 잘 된다.

기능 추가

1
2
3
4
5
func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
        var options = SwipeOptions()
        options.expansionStyle = .destructive
        return options
    }

Readme에 있는 부분을 가져와서 추가했다.

Apr-15-2024 18-50-51

완료.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.