Cannot convert value of type [AnyObject] to expected argument type [PFObject] -- Parse & Swift II Error - swift

This is the line that is failing, with error message "Cannot convert value of type [AnyObject] to expected argument type [PFObject]"
self.customObtainAllHandlerWithObjects(objects, success: success, failure: failure)
import UIKit
import Parse
class AbstractService: BaseService {
private let _cache = AbstractCache<T>()
private let _parser = AbstractParser<T>()
/// Store all completionHandlers for convertFromParseObject operations here. Need this to avoid a concurrent conversions of the same object.
var conversions = Dictionary<String, [(entity: T) -> Void]>()
/// Contains ids of objects, which need their videos to be downloaded.
var queue: [(entityId: String, file: PFFile)] = []
var isQueueDownloading = false
var className: String {
get {
fatalError("This property must be overridden")
}
}
// MARK: - Create
func createEntity() -> T {
let entity = T()
cache().appendEntity(entity)
return entity
}
// MARK: - Obtain all
/// Base method, which obtains entities from Parse database.
///
/// - parameter skip: Number of records, which will be skipped.
/// - parameter limit: Max number of entities returned.
/// - parameter constraints: A block, which applies constraints to PFQuery. E.g. query.includeKey("author") or query.whereKey("user", equalTo: PFUser.currentUser()).
/// - parameter success: Success block. Executes when operation successfully finished.
/// - parameter failure: Failure block. Executes when operation fails.
func obtain(skip skip: Int?, limit: Int?, constraints applyConstraints: ((query: PFQuery) -> PFQuery)?, success: (entities: [T]) -> Void, failure: FailureCompletionHandler) {
var query = PFQuery(className: className)
if let skip = skip {
query.skip = skip
}
query.limit = limit ?? 1000
if let applyConstraints = applyConstraints {
query = applyConstraints(query: query)
}
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let error = error {
self.callFailureCompletionHandler(failure, error: error)
}
else {
if let objects = objects {
self.customObtainAllHandlerWithObjects(objects, success: success, failure: failure)
}
else {
failure(allowRetry: false, errorMessage: "Cannot load \(self.className)")
}
}
}
}

You're getting this error because object is of type [AnyObject] but the function you're calling--customObtainHandler--is expecting PFObject so you're going to have to convert your object to a PFObject.
You can convert between types with the as keyword.
so you do something like this:
if let myVar as? PFObject {
// now myVar is a PFObject
}
I don't recommend this but you can also force convert it using:
myVar as! PFObject

Related

Unable to execute below closure due to parameter type in swift

I have a situation to upload content to S3 Bucket AWS.
I am using the below code and the code is not compiled.
Please advise.
let data = // The data to upload
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = {(task, progress) in DispatchQueue.main.async(execute: {
// Do something e.g. Update a progress bar.
})
}
let completionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
// Do something e.g. Alert a user for transfer completion.
// On failed uploads, `error` contains the error object.
})
}
let transferUtility = AWSS3TransferUtility.default()
transferUtility.uploadData(data,
bucket: S3BucketName,
key: S3UploadKeyName,
contentType: "image/png",
expression: expression,
completionHandler: completionHandler).continueWith { (task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let _ = task.result {
// Do something with uploadTask.
}
return nil;
}
I am getting 2 below errors.
Unable to infer type of a closure parameter 'error' in the current context.
Unable to infer type of a closure parameter 'task' in the current context

How can I type check a generic then cast to it in swift?

I like the ideas presented in this post, about making database-agnostic, protocol-oriented code.
So say I have a protocol such as:
protocol Database {
func loadObjects<T>(matching query: Query) -> [T]
func loadObject<T>(withID id: String) -> T?
func save<T>(_ object: T)
}
where Query is a struct that has filter and sort specifiers.
Then, given a persistence framework, such as Realm or CoreData, I can just support this protocol, as such:
extension NSManagedObjectContext: Database {
...
}
extension Realm: Database {
...
}
extension MockedDatabase: Database {
...
}
extension UITestingDatabase: Database {
...
}
The issue arises when I would want to use CoreData.
If we look at the method:
func loadObjects<T>(matching query: Query) -> [T]
I have no way to 'cast' T to NSManagedObject.
For example, my desired implementation might be something like:
extension NSManagedObjectContext: Database {
func loadObjects<T>(matching query: Query<T>) -> [T] {
// you need a fetch request for these models. This guard statement compiles. How do we make it work with NSFetchRequestResult however?
guard T.self is NSManagedObject.Type else {
return []
}
// This line below Fails compiling. Type 'T' does not conform to protocol 'NSFetchRequestResult'
var request = NSFetchRequest<T>(entityName: String(describing: T))
// then set sortDescriptors and predicate, etc.
var objects: [T] = []
self.performAndWait {
do {
if let results = try self.fetch(request!) as? [T] {
objects = results
}
} catch let error {
print("Error fetching: \(error.localizedDescription)")
}
}
return objects
}
}
So if I can determine if T's Type is a kind of NSManagedObject, then is it possible to instantiate a NSFetchRequest by 'casting' T to something that will work? It would seem I can't cast or force T to be anything.
Database is a technology-agnostic protocol and therefore shouldn't know anything about Core Data. I'd like to do this in the event I need to change my data persistence framework.
How might I accomplish this in Swift? Would I have to add to the Model protocol to return optionals that would be used for the given frameworks I would support? Or make them support NSFetchRequestResult? I would rather that only the implementation of the protocol need to care about the details of the persistence framework.
Rather than checking the type at runtime constrain the type at compile time, for example
extension NSManagedObjectContext: Database {
func loadObjects<T: NSManagedObject>(matching query: Query<T>) -> [T] {
let request = NSFetchRequest<T>(entityName: String(describing: T.self))
var objects = [T]()
self.performAndWait {
do {
objects = try self.fetch(request) // a generic fetch request returns an array of the generic type or throws an error
} catch let error {
print("Error fetching: \(error.localizedDescription)")
}
}
return objects
}
}
It looks like I can answer my own question. One can further constrain generic types by overloading them, so that the calling code can remain the same, but what gets called is dependent on the type you pass into it.
This code below demonstrates this in a playground:
public protocol Action {
func doSomething<T>(to object: T)
}
public class MyActor {
}
extension MyActor: Action {
// works for any type
public func doSomething<T>(to object: T) {
print("was generic")
}
// but if you constrain the type and your object fits that constraint...
// this code is called (same method signature)
public func doSomething<T: NSObject>(to object: T) {
print("was an object")
}
}
class MyObject: NSObject {
var name: String = "Object"
}
struct MyStruct {
var name: String = "Struct"
}
let actor = MyActor()
let object = MyObject()
let value = MyStruct()
actor.doSomething(to: value) // prints 'was generic'
actor.doSomething(to: object) // prints 'was an object'
So in the original example, I would then support Database for CoreData with:
extension NSManagedObjectContext: Database {
func loadObjects<T>(matching query: Query<T>) -> [T] {
return [] // return an empty array because we only support NSManagedObject types
}
func loadObjects<T: NSManagedObject>(matching query: Query<T>) -> [T] {
let request = NSFetchRequest<T>(entityName: String(describing: T.self))
var objects = [T]()
self.performAndWait {
do {
objects = try self.fetch(request) // a generic fetch request returns an array of the generic type or throws an error
} catch let error {
print("Error fetching: \(error.localizedDescription)")
}
}
return objects
}
}

Caching in Swift 4.2 using PromiseKit 6

I'm experiencing two errors:
pending = endpoint().then { freshValue in
Causes error: "Unable to infer complex closure return type; add explicit type to disambiguate"
return Guarantee(cachedValue) as! Guarantee<t>
Causes error: "Cannot convert value of type 'T' to expected argument type 'PMKUnambiguousInitializer'"
This was working in Swift 2 (slightly edited since), however since the update to Swift 4.2 this code begins to break. I'll admit, I'm still trying to figure out all the changes from Promisekit 4 to 6.
Here's the rest of the code:
import Foundation
import PromiseKit
class CachedValue<T> {
var date = NSDate.distantPast
var value: T? { didSet { date = NSDate() as Date } }
}
class Cache<T> {
private let defaultMaxCacheAge: TimeInterval
private let defaultMinCacheAge: TimeInterval
private let endpoint: () -> Guarantee<T>
private let cached = CachedValue<T>()
private var pending: Guarantee<T>?
// Always makes API request, without regard to cache
func fresh() -> Guarantee<T> {
// Limit identical API requests to one at a time
if pending == nil {
pending = endpoint().then { freshValue in
self.cached.value = freshValue
return Promise(freshValue)
}.ensure {
self.pending = nil
} as! Guarantee<T>
}
return pending!
}
// If cache too old (invalid), returns nil
func cachedOrNil(maxCacheAge: TimeInterval) -> T? {
// maxCacheAge is maximum cache age before cache is deleted
if NSDate().timeIntervalSince(cached.date) > maxCacheAge {
cached.value = nil
}
return cached.value
}
// If cache nil too old (stale), makes API request
func cachedOrFresh(maxCacheAge: TimeInterval, minCacheAge: TimeInterval) -> Guarantee<T> {
// minCacheAge is minimum cache age before API request is made
if let cachedValue = cachedOrNil(maxCacheAge: maxCacheAge) {
if NSDate().timeIntervalSince(cached.date) < minCacheAge {
return Guarantee(cachedValue) as! Guarantee<T>
}
}
return fresh()
}
/// ... More code in file...
}
Here you need to provide the return type from the then block by specifying the concrete type e.g, MyClass as below,
pending = endpoint().then { freshValue -> Guarantee<MyClass> in ...}

How do I determine the value of a generic variable at runtime?

The following snippet shows the generic variable 'A'.
I'm trying to figure out the source of nil being returned by this load().
Here's a the code snippet:
final class Cache {
var storage = FileStorage()
// 1) 'load': Read from the Cache:
func load<A>(_ resource: Resource<A>) -> A? {
print("--- LOAD ---")
guard case .get = resource.method else { return nil }
// Type of 'data' is optional.
let diskData = storage[resource.cacheKey] // ...type: Data? (optional-Data).
// Want to convert diskData to A? (optional-A):
return diskData.flatMap(resource.parse) // ...cleaning data, removing nils.
}
// 2) 'save' to the Cache:
func save<A>(_ data: Data, for resource: Resource<A>) {
print("--- SAVE ---")
guard case .get = resource.method else { return }
self.storage[resource.cacheKey] = data
}
}
// ----------------------------------
// MARK: - Resource
public struct Resource<A> {
public var url: URL
public var parse: (Data) -> A? // ... convert Data to A?
public var method: HttpMethod<Data> = .get
public init(url: URL, parse: #escaping (Data) -> A?, method: HttpMethod<Data> = .get) {
self.url = url
self.parse = parse
self.method = method
}
}
// ----------------------------------
In the meantime, How I can determine the value of any generic variable during runtime-debugging?
That is, who do I determine the value of A?
Note: code is from a shared source via 'Swift Talk' on objc.io.
To find out what type A represents, print the type of a variable that has a type that include the generic type placeholder.
In your case, resource has type Resource<A> so:
p type(of: resource)
will show something like:
<ProjectName>.Resource<Int>
in which case A is Int.

Trailing Closures on generics?

Hi I am trying to understand the following code from Alamofire. How can you initialise a struct with "{}" I know that you can call a closure with Trailing Closures. I know I am totally missing something, but what?
extension Request {
public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, NSError> -> Void) -> Self {
let responseSerializer = ResponseSerializer<T, NSError> { // What is this?
request, response, data, error in
guard error == nil else { return .Failure(error!) }
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
switch result {
case .Success(let value):
if let
response = response,
responseObject = T(response: response, representation: value)
{
return .Success(responseObject)
} else {
let failureReason = "JSON could not be serialized into response object: \(value)"
let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
return .Failure(error)
}
case .Failure(let error):
return .Failure(error)
}
}
return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
}
}
The struct ResponseSerializer from Alamofire
public struct ResponseSerializer<Value, Error: ErrorType>: ResponseSerializerType {
/// The type of serialized object to be created by this `ResponseSerializer`.
public typealias SerializedObject = Value
/// The type of error to be created by this `ResponseSerializer` if serialization fails.
public typealias ErrorObject = Error
/**
A closure used by response handlers that takes a request, response, data and error and returns a result.
*/
public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>
/**
Initializes the `ResponseSerializer` instance with the given serialize response closure.
- parameter serializeResponse: The closure used to serialize the response.
- returns: The new generic response serializer instance.
*/
public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) {
self.serializeResponse = serializeResponse
}
}
Your question can be greatly pared down (and should have been). Here is the relevant declaration of ResponseSerializer:
public struct ResponseSerializer<Value, Error: ErrorType>: ResponseSerializerType {
public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) {
self.serializeResponse = serializeResponse
}
}
So this initializer, init(serializeResponse:), takes one parameter — a function taking four parameters and returning one parameter (of the specified types).
Thus, we can initialize like this:
func f (request:NSURLRequest?, response:NSHTTPURLResponse?, data:NSData?, error:NSError?) -> Result<Value, Error>) {
guard error == nil else { return .Failure(error!)
}
let responseSerializer = ResponseSerializer<T, NSError>(serializeResponse:f)
However, this can be condensed. We don't really need the function f for anything else, so we can supply it as an anonymous function; it doesn't need a name or a full declaration. Moreover, there is a "shortcut" rule for anonymous functions, that if an anonymous function is the last parameter to a function, it can be provided literally after the function's closing parentheses, with the parameter name omitted. And if the function takes no other parameters, its parentheses can be omitted altogether.
Well, this init is exactly such a function — it takes a function as its last (and only) parameter — so that is exactly what the code in question does:
let responseSerializer = ResponseSerializer<T, NSError> {
request, response, data, error in
guard error == nil else { return .Failure(error!)
}
If I read it all correctly the code above has a pattern similar to this:
// just a something
struct Blah {
var stuffs : (message:String) -> Void
init(closure:(message:String) -> Void) {
self.stuffs = closure
}
}
// an extension because the code above is also in an extension, but not needed at all
extension Blah {
// a function with a closure that also returns an instance of Self
func spawnChild(closure:(message:String) -> Void) -> Blah {
return Blah(closure: closure) // closure is passed to spawn
}
}
Tests :
let alpha = Blah { (message) -> Void in
print("alpha",message)
}
let beta = alpha.spawnChild { (message) -> Void in
print("beta", message)
}
alpha.stuffs(message: "parrent") // alpha parent
beta.stuffs(message: "spawn") // beta spawn
Remember that the trailing closure is just syntactic sugar for an input parameter that is a closure. So anything that takes input parameters can have a trailing closure.