Ios 从API获取计数值后更新应用程序图标徽章编号

Ios 从API获取计数值后更新应用程序图标徽章编号,ios,swift,badge,Ios,Swift,Badge,我想通过合计所有徽章计数来更新应用程序图标徽章编号。以下是我的功能。问题是计数不同步,因为我从API获取计数值,而闭包使其不同步。updateBadgeCounts()在应用程序使用期间将被多次调用 我如何让它工作 extension UIViewController { func updateBadgeCounts() { fetchValue1() { (result, error) in UIApplication.shared.appli

我想通过合计所有徽章计数来更新应用程序图标徽章编号。以下是我的功能。问题是计数不同步,因为我从API获取计数值,而闭包使其不同步。updateBadgeCounts()在应用程序使用期间将被多次调用

我如何让它工作

extension UIViewController {

    func updateBadgeCounts() {
        fetchValue1() { (result, error) in
            UIApplication.shared.applicationIconBadgeNumber = result!.data!.count!
        }

        fetchValue2() { (result, error) in
           UIApplication.shared.applicationIconBadgeNumber += result!.data!.count!
        }
    }

}
调用上述函数

class MainTabBarController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {

        // Do other stuff...

        DispatchQueue.main.async() {
            self.updateBadges()
        }

    }

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        DispatchQueue.main.async() {
            self.updateBadges()
        }
    }

}

这两个值是通过单独的异步调用获取的,因此它们将在不同的时间返回

您可以将这两个值存储在视图控制器变量中,并使用
didSet
更新徽章

var value1: Int = 0 {
    didSet {
        updateBadge()
    }
}

var value2: Int = 0 {
    didSet {
        updateBadge()
    }
}

func updateBadge() {
    UIApplication.shared.applicationIconBadgeNumber = value1 + value2
}

func updateValues() {
    fetchValue1() { (result, error) in
        if let result = result {
            self.value1 = result.data!.count
        }
    }
    fetchValue2() { (result, error) in
        if let result = result {
            self.value2 = result.data!.count
        }
    }
}

另外,我添加了可选绑定来检查
result
是否为nil。根据您的数据,您可能需要以不同的方式处理它。例如,您可能需要将
结果.data
强制转换为特定类型。

这两个值是通过单独的异步调用获取的,因此它们将在不同的时间返回

您可以将这两个值存储在视图控制器变量中,并使用
didSet
更新徽章

var value1: Int = 0 {
    didSet {
        updateBadge()
    }
}

var value2: Int = 0 {
    didSet {
        updateBadge()
    }
}

func updateBadge() {
    UIApplication.shared.applicationIconBadgeNumber = value1 + value2
}

func updateValues() {
    fetchValue1() { (result, error) in
        if let result = result {
            self.value1 = result.data!.count
        }
    }
    fetchValue2() { (result, error) in
        if let result = result {
            self.value2 = result.data!.count
        }
    }
}

另外,我添加了可选绑定来检查
result
是否为nil。根据您的数据,您可能需要以不同的方式处理它。例如,您可能需要将
结果.data
转换为特定类型。

如果您还没有弄清楚,那么这里有一个解决方案。您可以在嵌套函数中实现它。像这样的

func updateValues() {
    fetchValue1() { (result, error) in
        fetchValue2() { (result, error) in
            // update all badges numbers here
        }
    }
}

如果你还没有弄明白,那么这里有一个解决方案。您可以在嵌套函数中实现它。像这样的

func updateValues() {
    fetchValue1() { (result, error) in
        fetchValue2() { (result, error) in
            // update all badges numbers here
        }
    }
}


你说它不同步是什么意思?您能否提供一些实际结果和预期结果的示例数据。假设fetchValue1中的计数为4,value2中的计数为10。当我关闭应用程序时,它会显示徽章编号4,然后在几秒钟后更新为14。有时总是显示4,有时是14。所以我不确定发生了什么,我假设这是由于没有在主线程中执行。@Josh我已经添加了一个答案。所以,只是为了检查一下,它有时确实正确地显示了全部总额?是的,它有时正确地添加了总额。你说它不同步是什么意思?您能否提供一些实际结果和预期结果的示例数据。假设fetchValue1中的计数为4,value2中的计数为10。当我关闭应用程序时,它会显示徽章编号4,然后在几秒钟后更新为14。有时总是显示4,有时是14。所以我不确定发生了什么,我假设这是由于没有在主线程中执行。@Josh我已经添加了一个答案。所以,只是为了检查,它有时确实正确地显示了全部总量?是的,它有时正确地添加了总量。Tx Chris,您理解的非常清楚,解决方案对我来说也很清楚。今天学到了新东西。我的问题仍未解决,因为updateBadgeCounts()是UIViewController扩展的函数,所以无法声明变量。我更新了我的问题以反映它。对不起,我应该早点做。@Josh好的,谢谢。您可以在原始视图控制器代码中声明变量,并在扩展中访问它,但我不确定这是否是一种好的做法。因此,可以运行嵌套在另一个异步调用中的一个异步调用,并仅在函数范围内使用变量。我将用这个选项更新我的答案。@Josh再想一想,您可能需要查看调度组,它可以处理多个异步调用。我对他们不是很熟悉。我在上面的评论中所建议的不太可能像预期的那样起作用。感谢您引入调度组。我已经做了一个快速阅读,它似乎是解决办法。我会做更多的阅读并尝试。@Josh每个异步任务完成后,似乎很容易收到通知,但我不知道如何在不使用变量的情况下轻松获取返回值。Tx Chris,您的理解非常清楚,解决方案对我来说也很清楚。今天学到了新东西。我的问题仍未解决,因为updateBadgeCounts()是UIViewController扩展的函数,所以无法声明变量。我更新了我的问题以反映它。对不起,我应该早点做。@Josh好的,谢谢。您可以在原始视图控制器代码中声明变量,并在扩展中访问它,但我不确定这是否是一种好的做法。因此,可以运行嵌套在另一个异步调用中的一个异步调用,并仅在函数范围内使用变量。我将用这个选项更新我的答案。@Josh再想一想,您可能需要查看调度组,它可以处理多个异步调用。我对他们不是很熟悉。我在上面的评论中所建议的不太可能像预期的那样起作用。感谢您引入调度组。我已经做了一个快速阅读,它似乎是解决办法。我将进行更多的阅读并尝试。@Josh每个异步任务完成后,似乎很容易收到通知,但我不知道如何在不使用变量的情况下轻松获取返回值。