ios - Swift - Parse Data Return in Email
问题描述
I'm currently building an app where you can read all your last 7 days HeartRate. Once you request the data it get displayed into a UITableView
, whenever the data is loaded you can send the results via an email button. Then after the email body get filled up with all the DataHeart. I'm looking to get only the Time & Heartbeat Rate but i can't figured a way to parse it clearly. Also whenever I press the submit or cancel button I can't return to the previous screen. The app doesn't crash or any error, it just wont let me go back.
Here's my code block:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getHealthKitPermission()
}
let healthStore = HKHealthStore()
var heartRateData: [HKSample]?
@IBOutlet weak var tblHeartRateData: UITableView!
@IBAction func getHeartRate(_ sender: Any) {
getTodaysHeartRate { (result) in
DispatchQueue.main.async {
self.heartRateData = result
self.tblHeartRateData.reloadData()
}
}
}
@IBAction func emailResult(_ sender: Any) {
self.sendEmail()
}
func getTodaysHeartRate(completion: (@escaping ([HKSample]) -> Void)) {
print("func")
let heartRateType:HKQuantityType = HKQuantityType.quantityType(forIdentifier: .heartRate)!
let startDate = Date() - 7 * 24 * 60 * 60
let endDate = Date()
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: [])
let sortDescriptors = [
NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
]
let heartRateQuery = HKSampleQuery(sampleType: heartRateType,
predicate: predicate,
limit: Int(HKObjectQueryNoLimit),
sortDescriptors: sortDescriptors)
{ (query:HKSampleQuery, results:[HKSample]?, error:Error?) -> Void in
guard error == nil else { print("error"); return }
completion(results!)
}
healthStore.execute(heartRateQuery)
}
func sendEmail() {
if let currentHeartRate = heartRateData{
if MFMailComposeViewController.canSendMail() {
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
let result = formatter.string(from: date)
let mail = MFMailComposeViewController()
mail.mailComposeDelegate = self as? MFMailComposeViewControllerDelegate
mail.setToRecipients([""])
mail.setMessageBody("<p>Your Heart Rate is: \(currentHeartRate)<p>" + result, isHTML: true)
present(mail, animated: true)
} else {
//Do nothing
}
}
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
controller.dismiss(animated: true)
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return heartRateData?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HeartDataTableViewCell
let heartRateUnit:HKUnit = HKUnit(from: "count/min")
let heartData = self.heartRateData?[indexPath.row]
guard let currData:HKQuantitySample = heartData as? HKQuantitySample else { return UITableViewCell()}
cell.labelTimes.text = "Times: \(startDateSring)"
cell.labelHeartRate.text = "Heart Rate: \(currData.quantity.doubleValue(for: heartRateUnit))"
let startDateFormatter = DateFormatter()
startDateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
startDateFormatter.timeZone = TimeZone.current
let startDateSring = startDateFormatter.string(from: currData.startDate)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return
}
}
解决方案
Your email sending function should look something like this:
guard let currentHeartRate = heartRateData else {
return
}
guard MFMailComposeViewController.canSendMail() else {
// show alert
return
}
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
let mail = MFMailComposeViewController()
// note that your view controller must conform to MFMailComposeViewControllerDelegate
mail.mailComposeDelegate = self
mail.setToRecipients([""])
let heartRateUnit = HKUnit.count().unitDivided(by: .minute())
let quantityStrings = currentHeartRate
.compactMap { $0 as? HKQuantitySample }
.map {
"<p>Your Heart Rate is: \($0.quantity.doubleValue(for: heartRateUnit)) on \(formatter.string(from: $0.startDate)) </p>"
}
mail.setMessageBody(quantityStrings.joined(separator: "<br>"), isHTML: true)
present(mail, animated: true)
Note that you need to conform to the mail compose delegate, e.g.:
extension ViewController: MFMailComposeViewController {
}
推荐阅读
- r - 如何在一个图中绘制来自不同模型的估计值
- python - 每次用户输入后如何正确显示菜单?
- python - Python:查询器验证功能
- python - 用于下载股票基本数据的 TWS API 只运行第一个数据条目并忽略其他数据。谁来解决这个问题?
- gradle - Flutter:尽管几分钟前它运行良好,但无法启动项目
- c# - Xamarin 悬停事件
- javascript - Redux 状态已填充但不会在组件中呈现
- ruby-on-rails - 从视图调用控制器方法的问题
- javascript - 使用 react-create-wptheme 创建应用程序后路由的 React-router-dom 问题
- html - 纯 CSS onclick 事件复选框 hack 问题