Swift cannot infer type from context
This question can only really be answered by a compiler engineer at Apple, and per the above commenters it could / should be considered a bug, but it is definitely a hole in their shorthand syntax. For questions like these, I have gotten good results from posting to devforums.
The simple rule though is that whenever you have multiple lines / need to use the return
keyword, you must either explicitly define the return type, or the type of the value being captured. This limitation might be due to the fact that in the compact / degenerate case, you are guaranteed to only have one point of exit - val in val
, where as when you use a return
keyword, it is possible to have multiple return points. In this latter case, you might return an Int on one line return 1
, and return nil
on another. In that case, it would be reasonable to have the compiler complain to make the assumption explicit. In short, this would require more sophisticated type inference in the compiler, and they might not have gotten to that yet.
So TL;DR, I agree with the suggestion to report this as a bug, and in the meantime, specify a return type from the closure. The point remains though that the compiler has enough context to infer the correct type, as you stated.
Note, that in addition to your example, these cases also work:
// inferring var dict as a context for lines below
var dict = arrayToDictionary([1, 2, 3], { val in val })
// dict is already defined, so this works:
dict = arrayToDictionary([1, 2, 3], { val in return val })
// explicit final type, compiler infers backwards
let d2:Dictionary<Int, Int> = arrayToDictionary([1, 2, 3], { val in val })
// explicit return type, compiler infers "forewards"
let d3 = arrayToDictionary([1, 2, 3], { val -> Int in return val })
SwiftUI: Cannot infer contextual base in reference to member
As @jnpdx is referring to with the Xcode versions, the Swift version may not be the same. In Swift 5.4, SE-0287 was implemented.
This proposal allowed for implicit member chains. You can read more on the proposal linked, but this sums it up pretty well:
This proposal suggests the expansion of implicit member syntax to more complex expressions than just a single static member or function. Specifically, implicit member syntax would be allowed to cover chains of member references.
Code such as Color.red.opacity(0.5)
can now be simplified to .red.opacity(0.5)
, similar to in your example.
Xcode 12.5 is required to use Swift 5.4, so let the team know to upgrade.
unable to infer type in flatMap
From what I can see in your code... you haven't told it what result
is. Even reading it as a human I can't tell what it is supposed to be.
Your fetchData
function returns an AnyPublisher
of generic type T
.
Your getCountryStats
function takes that generic type T
into a flatMap
function and returns an AnyPublisher
of type [CountryDayOneResponse]
.
But at no point do you tell it what T
is. You don't even tell it what result
is. Only the output of the flatMap
function.
What is the type of result
expected to be?
Edit after comment.
If you want your result
to be [CountryOneDayResponse]
then this code will do...
func getCountryStats(for countryName: String) -> AnyPublisher<[CountryDayOneResponse], ErrorType> {
let url = RestEndpoints.countryStats(countryName: countryName).endpoint()
let publisher: AnyPublisher<[CountryDayOneResponse], ErrorType> = NetworkManager().fetchData(url: url)
return publisher
.flatMap{ Just(Array($0.sorted(by: {$0.date > $1.date}))) }
.eraseToAnyPublisher()
}
You don't need to switch on the result like you are doing in the flatMap
as the flatMap
will only be entered if the publisher returns a non-error. So you can treat the input of the flatMap
as the success type of the publisher [CountryOneDayResponse]
.
Unable to infer closure type in the current context
The reason why it is not inferring the closure type is because the try
statement is not handled. This means that the closure expected to "catch"
the error, but in your case, you forgot the do-try-catch
rule.
Therefore you can try the following answer which will catch your errors:
do {
let imageAsData = try Data(contentsOf: imageURL)
let image = UIImage(data: imageAsData)
let ImageObject = Image()
ImageObject.image = image
self.arrayOfImgObj.append(ImageObject)
} catch {
print("imageURL was not able to be converted into data") // Assert or add an alert
}
You can then assert an error (for testing), or what I would personally do, is set up an alert.
This way the app wouldn't crash, but instead, notify the user. I find this very helpful when on the go and my device isn't plugged in - so I can see the error messages instead of a blank crash with no idea what happened.
Related Topics
How to Move Application's Window Between Virtual Desktops in Os X
Create a Loading Image/ Activity Indicator, Until the Image Is Shown in the Screen in Swift
Convert String to Staticstring
Integrate Existing Aws Cognito User Pool into iOS Project with Amplify
Firebase iOS Receive Data from Push Notification
Textfield Delegate Shouldchangecharactersinrange
How to Conform an Observableobject to the Codable Protocols
Swift:Pause and Resume Nstimer
Adding Animation to Tabviews in Swiftui When Switching Between Tabs
Attrackingmanager Stopped Working in iOS 15
How to Select All Text in a Uitextfield Using Swift
Format Println Output in a Table
Partial Application of 'Mutating' Method Is Not Allowed
Convert Optional String to Int in Swift
Is There an Kotlin Equivalent 'With' Function in Swift