>source

현재 SwiftUI를 사용하여 응용 프로그램을 개발 중입니다.

생성 된 가치를 사용하고 싶습니다. while 루프를 사용하여 DispatchGroup 조건으로 while 고리.

하지만 내 코드가 작동하지 않습니다 ... 내 목표는 시작일로부터 설정된 총 온도 이상의 날짜를 얻는 것입니다.

이 문제를 어떻게 해결할 수 있습니까?

<시간 />

업데이트 됨

예를 들면 :

아래와 같은 방법을 호출하면.

makeGetCallDateOverSetTemp(start_date:"2020-11-01", set_temp:100)

  • 첫 번째 루프->totalTemp = 20 (2020-11-01의 온도는 20 ℃)
  • 2 번 루프->totalTemp = 50 (2020-11-02 온도는 30 ℃)
  • 3 번 루프->totalTemp = 80 (2020-11-03 온도는 30 ℃)
  • 4 번 루프->totalTemp = 105 (2020-11-04의 온도는 25 ℃)

그만큼 while 루프는 여기서 멈추고 2020-11-04 설정 온도를 초과하는 날로.

<시간 />

AppState.swift

@Published var weatherInfos:[WeatherInfos]?
func makeGetCallDateOverSetTemp(start_date:String, set_temp:Int){
    
    let start_date = self.dateFromString(string: start_date, format: "yyyy/MM/dd")
    var addDays = 0
    var totalTemp:Float = 0.0
    
    let group = DispatchGroup()
   
    // Set up the URL request
    while Float(set_temp) < totalTemp {
        
        let start_date = Calendar.current.date(byAdding: .day, value: addDays, to: start_date)
        let url_start_date = self.stringFromDate(date: start_date!, format: "yyyy-MM-dd")
        
        let endpoint: String = "https://sample.com/api/weather/?start_date=\(url_start_date)"
        addDays += 1
        
        guard let url = URL(string: endpoint) else {
            print("Error: cannot create URL")
            continue
        }
        var urlRequest = URLRequest(url: url)
        urlRequest.addValue("token xxxxxxxxxxx", forHTTPHeaderField: "authorization")
        // set up the session
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
        // make the request
        group.enter()
        let task = session.dataTask(with: urlRequest) {(data, response, error) in
            guard error == nil else {
                print("error calling GET")
                return
            }
            // make sure we got data
            guard let responseData = data else {
                print("Error: did not receive data")
                return
            }
            // check for any errors
            defer { group.leave()}
            // parse the result as JSON, since that's what the API provides
            DispatchQueue.main.async {
                do{
                    self.weatherInfos = try JSONDecoder().decode([WeatherInfos].self, from: responseData)
                    for info in self.weatherInfos!{
                        totalTemp += info.temp
                    }
                }catch{
                    print("Error: did not decode")
                    return
                }
            }
        }
        task.resume()
    }
    group.notify(queue: .main){
    print(url_start_date)
    }
}
func stringFromDate(date: Date, format: String) -> String {
    let formatter: DateFormatter = DateFormatter()
    formatter.calendar = Calendar(identifier: .gregorian)
    formatter.dateFormat = format
    return formatter.string(from: date)
}
func dateFromString(string: String, format: String) -> Date {
    let formatter: DateFormatter = DateFormatter()
    formatter.calendar = Calendar(identifier: .gregorian)
    formatter.dateFormat = format
    return formatter.date(from: string) ?? Date()
}

jsonModel.swift

struct WeatherInfos:Codable,Identifiable {
    var id: Int
    var temp: Float
}

<시간 />
  • 답변 # 1

    while 조건이 비동기 작업의 결과에 의존하는 루프는 불가능합니다.

    이것은 Playground에서 실행되는 재귀가있는 독립 실행 형 일반 예제입니다.

    정적 데이터는 구조체, 배열, 대기열 및 임계 값입니다.

    struct Item {
        let date : String
        let values : [Int]
    }
    let items = [Item(date: "2020-02-01", values: [1, 3, 5]),
                 Item(date:"2020-02-02", values:[2, 4, 6]),
                 Item(date: "2020-02-03", values:[3, 5, 7])]
    let queue = DispatchQueue(label: "Foo")
    let threshold = 25
    
    

    변수는 지수와 누적 온도입니다.

    var temp = 0
    var index = 0
    
    

    함수 getData 다음을 전달하는 자신을 호출 item 임계 값에 아직 도달하지 않은 경우. 비동기 작업은 다음과 같이 시뮬레이션됩니다. asyncAfter .

    마지막으로 기능 notify 호출됩니다.

    func notify(date : String) {
        DispatchQueue.main.async{ print(date, temp) }
    }
    func getData(date: String, values :[Int]) {
        queue.asyncAfter(deadline: .now() + 1) {
            for value in values {
                temp += value
                if temp >= threshold {
                    notify(date: date)
                    return
                }
            }
            index += 1
            if index < items.count {
                let nextItem = items[index]
                getData(date: nextItem.date, values: nextItem.values)
            } else {
                notify(date: "\(date) – temperature below threshold")
            }
        }
    }
    let firstItem = items[index]
    getData(date: firstItem.date, values: firstItem.values)
    
    

관련 자료

  • 이전 PHP와 Javascript JWA 간의 다른 디지털 서명 결과
  • 다음 angular - 로컬 저장소에서 데이터를 검색하려는 문제