My app AirCompare is a smart home controller and makes system decisions based on local weather. Users have been seeing absurdly wrong (~10°F off) current temperatures, and of course that's a problem.
I've seen similar complaints on Reddit and one poster claims that Apple switched from whatever DarkSky was using (which seemed accurate) to a predictive model from IBM. Compare iOS15 to iOS16 and you may see a large discrepancy in the Weather app.
As a developer needing an accurate current temperature, I'm wondering if this is a temporary problem or whether we can expect this to continue going forward. If it's the latter, I'll need to find something more reliably accurate.
Post
Replies
Boosts
Views
Activity
I asked a similar question a while back:
https://developer.apple.com/forums/thread/730946
Since then I have a new Mac and new iPhone and so I now have the hardware to actually play with WeatherKit. I've worked my way past all the entitlements stuff and have been able to use and expand on online examples. Cool.
Trouble is, nearly every example you can find uses code designed to update the UI as fresh weather data is fetched. My app currently uses background URL fetches to obtain weather data, make some calculations and take appropriate actions, all in the background. Updating the UI was a separate challenge.
So which asynchronous tool is the right one for this? How can I quickly update my existing code to call WeatherKit instead of going to a weather site for a download?
I currently use something like a download task session:
let weatherTask = session.downloadTask (with: URL(string: urlString)!)
weatherTask.taskDescription = "weather"
weatherTask.resume()
or a dataTask session:
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue("text/html", forHTTPHeaderField: "Content-Type")
let taskWeatherPOP = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print("Error is \(String(describing: error))")
}
if let POPData = data,
let report = String(data: POPData, encoding: String.Encoding.utf8) {
if weatherReportPOP.contains("ServiceUnavailable") {
print("A Weather POP report error")
} else {
weatherReportPOP = report
} // Close the IF service unavailable
} // Closes the IF weather data is not nil
} // Close Task Weather
taskWeatherPOP.resume()
I'm getting my feet wet with weatherKit and have managed to get all the current weather I need with the code below.
My app requires one more thing - the chance of precipitation in the next 0-20 minutes or so - in order to close the windows if the odds exceed some threshold.
I haven't been able to find a single code example of retrieving the forecasted rain odds. It looks like the number I need will be in the MinuteWeather contained? in the HourlyForecast but it's completely a mystery to me how to extract what I need. I need a trail of breadcrumbs!
I tried getting the hourly and daily forecasts but the value I'm looking for isn't there.
import Foundation
import WeatherKit
@Observable class WeatherManager {
private let weatherService = WeatherService()
var weather: Weather?
func getWeather(lat: Double, long: Double) async {
do {
weather = try await Task.detached(priority: .userInitiated) { [weak self] in
return try await self?.weatherService.weather(for: .init(latitude: lat, longitude: long))
}.value
} catch {
print("Failed to get weather data. \(error)")
}
print("\(weather)")
do {
let daily = try await weatherService.weather(for: .init(latitude: lat, longitude: long), including: .daily)
let hourly = try await weatherService.weather(for: .init(latitude: lat, longitude: long), including: .hourly)
print("Daily: \(daily)")
print("Hourly: \(hourly)")
} catch let error {
print("Failed to get the forecast. \(error)")
}
} // close getWeather function
var icon: String {
guard let iconName = weather?.currentWeather.symbolName else { return "--" }
return iconName
}
var temperature: String {
guard let temp = weather?.currentWeather.temperature else { return "--" }
let convert = temp.converted(to: .fahrenheit).value
return String(Int(convert)) + "°F"
}
var humidity: String {
guard let humidity = weather?.currentWeather.humidity else { return "--" }
let computedHumidity = humidity * 100
return String(Int(computedHumidity)) + "%"
}
var pressure: String {
guard let press = weather?.currentWeather.pressure else { return "--" }
let convertP = press.converted(to: UnitPressure.inchesOfMercury).value
return String((convertP)) + " in. Hg"
}
var UVindex: String {
guard let uv = weather?.currentWeather.uvIndex.value else { return "--" }
return "\(uv)" + " index"
}
var POP: String {
????
return String(Int(chance)) + "%"
}
}
Can it be done?
I can reliably crash Xcode by attempting the following in a playground:
import UIKit
import WeatherKit
import CoreLocation
let sanFrancisco = CLLocation(latitude: 37.7749, longitude: 122.4194)
let weatherService = WeatherService()
let weather = try await weatherService.weather(for: sanFrancisco)
let temperature = weather.currentWeather.temperature
print(temperature)
Xcode 14.3.1
macOS 13.4.1
Sorry if this is a stupid question but I haven't been able to find any information on whether an app can request and receive weatherKit data - the weather - while in the background.
My app (AirCompare) makes extensive use of background URL sessions to fetch and process weather data. If certain conditions are met, a notification alert is sent to the user so the user can decide whether to activate the app. For instance if rain is in the forecast, the app alerts the user that they might want to close their windows. Making the app active will execute HomeKit control and accomplish that.
Will I be able to replace the background URL session with the appropriate code and be able to fetch weather data in the background?
I'd like to find a way to control the display backlight brightness using the method in use before Mojave. The method I'm looking for may be even older.I have one of the cursed late-2011 Macbook Pros with the failed AMD Radeon graphics. Using the excellent solution from dosdude, I have disabled the AMD discrete graphics and everything runs fine using the Intel graphics. Everything EXCEPT adjusting screen brightness. (I think there are other issues with sleep but that doesn't concern me.) Symptoms include no response to the F1 and F2 buttons and no slider in System Preferences. Most folks get max brightness all the time. I was living with that until a recent update to 10.14.6. Now I'm locked at some lower level.Loss of brightness control is a well-documented shortcoming of the dosdude fix. It's a small price to pay to unbrick your Macbook! But it would be awesome to restore dimming.Anyway, the loss of brightness control corresponds to a system upgrade. I think dimming worked fine under Sierra but disappeared with High Sierra. Possibly it was Mojave that killed it. I'm sure the details are in the dosdude patch thread and I could retrieve those details if it matters. The possibility of returning to the dimming control used back then is tantalizing. Maybe that's because I have no idea how impossible it is?If there was an easy approach to this I'm pretty sure a talented guy like dosdude would have found it. So I'm wondering if he left some stone unturned. Some kext replacement or such that might restore dimming to all of us suffering along with one of Apple's rare lemon models.
I have a couple apps that use text pickers and I've noticed a text alignment problem where left-aligned text is shoved so far left that the leftmost character or two gets cut off. The problem started with iOS 14 and continues in iOS 15. I have a kludge fix that adds two spaces to the beginning of the text string to be displayed in the picker. It works great, but I'd like to better understand what's going on.
I've noticed that it's widely known that date pickers behave differently as of iOS 14. I haven't seen anything about text pickers. Does anyone know of a change that might effect text alignment in text pickers as of iOS 14?
The details of my issue are available at stack overflow.
I was working on my app in Xcode and, after making some changes in Interface Builder and installing to my iPhone, this error popped up:error: failed to launch '/private/var/containers/Bundle/Application/long number/MyApp.app' -- X’s iPhone6 has denied the launch request. (Where X is me).I've tried:Quitting and relaunching XcodePowering down and restarting the iPhoneInstalling the latest Xcode beta 9.1 Beta 9B46Toggling the checkmark for "Automatically manage signing"Using Simulator (which works) I've found reference to this error elsewhere and some people had success by paying attention to their signing. I'm signing as an iOS Developer, so I don't know what else to do.
I have a background operation (a web fetch) that grabs some data from the internet. I need to dispatch out that data as soon as possible during the fetch and have been using the following: func dispatchWebData(myNumber: Double) {
if UIApplication.shared.applicationState == .active {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
self.myFunction(myNumber: myNumber)
}
} else {
DispatchQueue.global(qos: .userInteractive).asyncAfter(deadline: .now() + 0.2) {
self.myFunction(myNumber: myNumber)
}
}
}If the app is active, data handling is dispatched to the Main thread and the UI gets updated as soon as the data is available. If the app is not active, the main thread is not available so I dispatched data handling to the global thread. This was/is working fine.Now the MainThread Checker is sending me the little purple square warning that "UIApplication.applicationState must be used from main thread only".First, it seems silly that you can't check the application state from the background. What's the point if you can only check the state while the state is Active?But I wouldn't care about that issue as long as I can get my data handling to move forward. So I'm wondering is if I can check for the existence of the main thread and then dispatch to it if it's there, otherwise to the global thread. Other ideas welcome.
With iOS 14 there is a new privacy protection: Any attempt by an app to access the user's local network now causes a user to see an alert that the app "would like to find and connect to devices on your local network".
For instance, see an earlier thread on this:
https://developer.apple.com/forums/thread/654243
The rationale for this from Apple:
https://developer.apple.com/videos/play/wwdc2020/10110/
According to Apple's presentation above:
If your app just accesses resources on the wide internet, you don't need to do anything different. You also don't need to update if you only interact with the local network using a system service, like AirPrint, AirPlay, AirDrop, or HomeKit.
These system services handle device discovery without exposing the full list of devices to apps. On the other hand, if your app accesses the local network directly within your app, either with unicast or multicast protocols, your app will require permission.
You'll also need to make a few simple updates to your app for iOS 14." Fine, but my troubled app does not need any local network information. It does look for the user's location (which might use local network information?) and also accesses the internet. Another app of mine uses the same information to a much larger degree and is not causing any problem.
In Simulator (iPhone 11 Pro running iOS 14.0), my app does not appear on the list of "Apps that have requested permission to find and connect with devices ...". The app is running fine as expected. I cannot replicate the alert that is causing my app to be rejected. I don't know how to fix it!
A similar discussion here:https://forums.developer.apple.com/message/73484#73484I'm controlling an Ecobee 3 thermostat and a couple of switched outlets with my app (called AirCompare and in the store) using HomeKit. It works well and I've been running it continuously for over a year. The thermostat responds more slowly than the switches and sporadically I get the rare error shown in the title. The user sees only a red dot indicating an error but the text of the error prints to my log file. The error can usually be cleared by the user by taking any of a number of actions in the app that will call the Home Manager again.I thought this occasional error might have something to do with the thermostat's slow response causing something to time out, but the text of the error suggests someting else is screwy.I'm lost as to where to begin. I'd like to make this error even more rare. I'm thinking of adding another call of HM if the error is produced but this feels kludgy and I'd have to protect against an endless loop if the error persisted.
My first app and my first experience with iTunes Connect. I can add and delete users, and assign their roles when I add them, but I cannot edit them once added. The only thing I can do is "Resend Invitation".I'm logged in as myself with the Admin/Legal role. I have assigned all my other users the "Developer" role. The only Apple ID that is not greyed out in my list of users is my own. If I double-click my own AppleID to edit my roles, I can see that every checkbox is selected.https://help.apple.com/itunes-connect/developer/#/deva097c6c29I've read the above, but it mentions just double-clicking the user's AppleID in order to edit that user's roles an app access. But I can't do that.What am I missing?
I've been struggling to figure out why my app misbehaves for a few users. Their systems seem to be hostile towards the app. It's being sent to the background from the active state, and once in the background it seems to be quickly suspended. I do not see this on my phone or in Simulator, so it's very hard to diagnose. I have good logging that can detail background operation, but the logs die along with the app.The app is designed for longrun operation in the background. When the system allows, it gets some web data and reports to the user via a local notification. It's complicated but it all works, except for a few users. The app additionally has a "Night Mode", where it remains the active app all night and web data is gathered every 10 minutes on a timer. Mine ran perfectly all night last night but a user log shows the app was backgrounded after just 3 minutes. It must have also suspended shortly after that because there are zero log entries until the user woke up in the morning and logging resumed. That particular user is getting some background fetches this morning, so at least we know the proper permission settings are in place.What would cause an app to be so aggressively demoted?
Years ago I submitted a request to obtain entitlement for my app to access HomeKit from the background. There was a rumor back then that there was a secret background entitlement to enable this, and that's exactly what I needed.
Today I received a cryptic Feedback from Apple on that old request:
"After reviewing your feedback, we have some additional information for you:
The HomeKit entitlement is public now. Please close your feedback if this is no longer an issue for you. Thanks!"
What does this mean? I suspect it has nothing to do with what I asked for.
My app uses HomeKit to control a few accessories and it seems to work fine. But while connected to the Debugger in Xcode, I'm seeing a lot of these reports:Date, time myApp[] [Messaging.Dispatcher] No handlers for message: HMFMessage kCharacteristicValueUpdatedNotificationKey(big key)I believe the source of the message may be my Ecobee 3 thermostat. I use a couple switched outlets also but I don't think these warnings have occur when I interact with them.Is there something I can do to intercept the message and eliminate the debugger warning? I don't really care what the debugger is saying or not, but I'm suspicious that there may be a performance problem when I interact with the Ecobee, and I'm hopeful that handling the message properly might help with that. The performance problem is generally slow responsiveness and an occasional failure to respond to a temperature change.