You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift+Alamofire实现事件按距离及日期排序并筛选近一周事件求助

Solution for Date Filtering & Sorting in Swift with Alamofire

Hey there! Since you’ve already got location and distance sorting working with Alamofire, let’s build on that to add the date-based filtering and sorting you need. Here’s a step-by-step breakdown tailored to your setup:

1. Prep Your Event Model for Date Handling

Assuming you have a Codable model for your events (if not, you’ll want one to parse the JSON cleanly), add computed properties to extract and validate the event dates from your eventDate1 to eventDate5 fields:

import Foundation

// First, define a reusable date formatter (match this to your JSON date format!)
let eventDateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" // Replace with your actual JSON date string format
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    return formatter
}()

struct Event: Codable {
    // Your existing properties (id, name, location coords, etc.)
    let eventDate1: String?
    let eventDate2: String?
    let eventDate3: String?
    let eventDate4: String?
    let eventDate5: String?
    
    // Get all valid Date objects from the 5 date fields (ignore nil/invalid strings)
    var validEventDates: [Date] {
        let dateStrings = [eventDate1, eventDate2, eventDate3, eventDate4, eventDate5]
        return dateStrings.compactMap { dateStr in
            guard let str = dateStr else { return nil }
            return eventDateFormatter.date(from: str)
        }
    }
    
    // Get the most relevant date for sorting/filtering (adjust based on your needs:
    // - Use max() for the latest event date
    // - Use min() for the earliest
    // - Or custom logic to pick the date closest to now)
    var primaryEventDate: Date? {
        return validEventDates.max() // Using latest date as primary
    }
}

2. Add Date Filtering Logic

We’ll filter events to only include those with at least one date that falls within your required range: no earlier than 1 week ago, and no later than the event’s own date (note: the "no later than event date" check is redundant since the date is the event’s own date—if you meant "no later than today", just replace date <= date with date <= Date()).

// Calculate the cutoff date (1 week before now)
let oneWeekAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())!

// Filter your events array (after parsing from Alamofire response)
let filteredEvents: [Event] = yourAlamofireEventsArray.filter { event in
    // Check if any of the event's valid dates meet the criteria
    return event.validEventDates.contains { date in
        date >= oneWeekAgo && date <= date // Adjust to date <= Date() if you mean "no later than today"
    }
}

3. Implement Date Sorting

Now sort the filtered events by their primary date (latest first, or earliest first—adjust the comparison as needed):

// Sort filtered events by primary date (latest first)
let sortedByDateEvents = filteredEvents.sorted { eventA, eventB in
    guard let dateA = eventA.primaryEventDate, let dateB = eventB.primaryEventDate else {
        // Handle events with no valid dates (e.g., push them to the end of the list)
        return false
    }
    return dateA > dateB // Reverse to dateA < dateB for earliest first
}

4. Integrate with Existing Distance Sorting

If you want to toggle between distance and date sorting, wrap everything in a helper function that takes a sort option:

import CoreLocation

enum SortType {
    case distance(userLocation: CLLocation)
    case date
}

func sortAndFilterEvents(events: [Event], by sortType: SortType) -> [Event] {
    // First apply date filter
    let oneWeekAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())!
    let filtered = events.filter {
        $0.validEventDates.contains { $0 >= oneWeekAgo && $0 <= Date() } // Adjusted to "no later than today" as a likely intended behavior
    }
    
    // Apply sorting based on selected type
    switch sortType {
    case .distance(let userLocation):
        // Your existing distance sorting logic
        return filtered.sorted { eventA, eventB in
            let locA = CLLocation(latitude: eventA.lat, longitude: eventA.lng) // Replace with your event's location properties
            let locB = CLLocation(latitude: eventB.lat, longitude: eventB.lng)
            return locA.distance(from: userLocation) < locB.distance(from: userLocation)
        }
    case .date:
        return filtered.sorted {
            guard let dA = $0.primaryEventDate, let dB = $1.primaryEventDate else { return false }
            return dA > dB
        }
    }
}

// Usage example:
// let sortedByDate = sortAndFilterEvents(events: yourEventsArray, by: .date)
// let sortedByDistance = sortAndFilterEvents(events: yourEventsArray, by: .distance(userLocation: userCurrentLocation))

Key Adjustments for Your Setup

  • Date Format: Make sure eventDateFormatter uses the exact format of your JSON date strings (common formats include "yyyy-MM-dd" or "MM/dd/yyyy HH:mm").
  • Primary Date Logic: Adjust the primaryEventDate computed property if you need to use a different date (e.g., earliest date instead of latest, or the date closest to the user’s current time).
  • Filter Edge Cases: If you want to exclude events with no valid dates entirely, add a check to the filter: !event.validEventDates.isEmpty && ....

Let me know if you need help tweaking any part to fit your specific model structure or JSON format! 😊

内容的提问来源于stack exchange,提问作者Geoff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:10:35