iOS Firebase를 활용한 신고 기능 구현하기

호씨·어제
0

iOS Firebase를 활용한 신고 기능 구현하기 🔍

모델 구현 💾

Report.swift

struct Report: Codable {
    @DocumentID var id: String?
    
    let reportReason: String      // 신고 사유
    let reportDetails: String     // 상세 내용
    let title: String            // 게시글 제목
    let reporterNickname: String  // 신고자 닉네임
    let creationTime: String      // 작성 시간
    let nickname: String          // 신고받는 사람 닉네임
    
    var toDictionary: [String: Any] {
        return [
            "reportReason": reportReason,
            "reportDetails": reportDetails,
            "title": title,
            "reporterNickname": reporterNickname,
            "creationTime": creationTime,
            "nickname": nickname
        ]
    }
}

Post.swift (기존 모델)

struct Post: Identifiable, Codable {
    @DocumentID var id: String?
    
    let nickName: String
    let postType: String
    let title: String
    let detail: String
    let position: [String]
    let techStack: [String]
    let ideaStatus: String
    let meetingStyle: String
    let numberOfRecruits: String
    let createdAt: Date
    
    // 팀원구함 전용 필드
    var urgency: String?
    var experience: String?
    
    // 팀 구함 전용 필드
    var available: String?
    var currentStatus: String?
}

서비스 레이어 구현 🔧

ReportManager.swift

class ReportManager {
    static let shared = ReportManager()
    private let db = Firestore.firestore()
    private let reportCollection = "reports"
    
    private init() {}
    
    func uploadReport(_ report: Report, completion: @escaping (Result<Void, Error>) -> Void) {
        do {
            let data = try Firestore.Encoder().encode(report)
            db.collection(reportCollection).addDocument(data: data) { error in
                if let error = error {
                    completion(.failure(error))
                } else {
                    completion(.success(()))
                }
            }
        } catch {
            completion(.failure(error))
        }
    }
    
    func getCurrentTime() -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy/MM/dd"
        return formatter.string(from: Date())
    }
}

화면 구현 📱

ReportVC.swift

신고 기능의 핵심 로직은 다음과 같다:

@objc private func reportButtonTapped() {
    // 1. 유효성 검사
    guard let selectedReason = selectedReason else {
        showAlert(title: "알림", message: "신고 사유를 선택해주세요.")
        return
    }
    
    let description = reportDescriptionTextView.text ?? ""
    if description.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
        showAlert(title: "알림", message: "신고 내용을 입력해주세요.")
        return
    }
    
    // 2. Report 객체 생성
    let report = Report(
        reportReason: selectedReason,
        reportDetails: description,
        title: post.title,
        reporterNickname: reporterNickname,
        creationTime: ReportManager.shared.getCurrentTime(),
        nickname: post.nickName
    )
    
    // 3. Firebase에 업로드
    ReportManager.shared.uploadReport(report) { [weak self] result in
        switch result {
        case .success:
            self?.showCompletionAlert()
        case .failure(let error):
            self?.showAlert(title: "오류", 
                          message: "신고 접수 중 오류가 발생했습니다: \(error.localizedDescription)")
        }
    }
}

Firebase 보안 규칙 설정 🔒

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /reports/{report} {
      allow read: if request.auth != null;
      allow create: if request.auth != null;
      allow update, delete: if false;  // 신고는 수정/삭제 불가
    }
  }
}

개선 사항 🚀

1. 신고 내역 조회 기능 추가

func getReports(completion: @escaping (Result<[Report], Error>) -> Void) {
    db.collection(reportCollection)
        .order(by: "creationTime", descending: true)
        .getDocuments { snapshot, error in
            // 처리 로직
        }
}

2. 신고 횟수 제한 로직

func checkReportLimit(userNickname: String, completion: @escaping (Bool) -> Void) {
    db.collection(reportCollection)
        .whereField("reporterNickname", isEqualTo: userNickname)
        .whereField("creationTime", isGreaterThan: Date().addingTimeInterval(-86400))
        .getDocuments { snapshot, _ in
            let count = snapshot?.documents.count ?? 0
            completion(count < 5)  // 하루 5회로 제한
        }
}

추가로 구현할 내용 📝

  1. 실제 사용자 닉네임 연동
  2. 신고 횟수 제한
  3. 신고 내역 조회 기능
  4. 관리자 페이지 연동
  5. 중복 신고 방지
  6. 빈칸 있을시 신고하기 버튼 비활성화
profile
이것저것 많이 해보고싶은 사람

0개의 댓글

관련 채용 정보