iosswiftxcodeadmobnative-ads

Issue with adding Data to an AnyObject Var so that I could make native ads work


 for postdata in postdata {
        if index < tableViewItems.count {
            tableViewItems.insert(postdata, at: index)
            index += adInterval
        } else {
            break
        }
    }

I'll need to add both PostData ads and Native Ads on the same AnyObject Var for me to get it to work and I can't find a way to add the Post Data because it says an error appears saying "Argument type 'PostData' expected to be an instance of a class or class-constrained type." Assistance would be very much appreciated, thank you.

edit 1

class Ad {
    var postimage: String!
    var publisher: String!
    var timestring: String!
    var timestamp = Date().timeIntervalSince1970
}

class PostDataAd: Ad {

    // Declare here your custom properties
    struct PostData1
    {
        var postimage: String
        var publisher: String
        var timestring : String
        var timestamp = Date().timeIntervalSince1970
    }
}

class NativeAd: Ad {
    // Declare here your custom properties
    struct NativeAd
    {
        var nativeAds: [GADUnifiedNativeAd] = [GADUnifiedNativeAd]()
    }
}

My model class to merge both Data into one AnyObject Var

and then trying to append the Data from Firebase by doing this

var ads: [Ad] = [PostDataAd(), NativeAd()]

let postList = PostDataAd.PostData1(postimage: postimage, publisher: 
postpublisher, timestring: postid, timestamp: timestamp)

self.ads.insert(postList, at:0)

an error occurs saying Cannot convert value of type 'PostDataAd.PostData1' to expected argument type 'Ad'


Solution

  • I hope I got what you want correctly. So basically you have two objects which you want to store in one array, under AnyObject. If that is correct, I recommend you to go in a bit of different direction. It is a nice example where you can use subclassing. You can declare a class called Ad, where you define the common properties which will be true for both PostDataAds and NativeAds.

    class Ad {
        // Add here the common elements you want to retrieve from both classes
        var name: String = ""
    }
    

    After you define your PostDataAds and NativeAds inheriting from Ad:

    class PostDataAd: Ad {
        // Declare here your custom properties
    }
    
    class NativeAd: Ad {
        // Declare here your custom properties
    }
    

    And if you want to define an array with two types of objects you can go:

    let ads: [Ad] = [PostDataAd(), NativeAd()]
    

    When retrieving you can check their type:

    if let item = ads.first as? PostDataAd {
         // The Ad is a PostDataAd
    } else if let item = ad as? NativeAd {
        // The Ad is a NativeAd
    }
    

    Or at some cases you don't even how to know the exact type, as you can access the properties defined in Ad without checking.

    Update:

    First of all your PostData1 and Ad objects are the same, you don't need to duplicate them. If you really want to have two classes you can inherit PostData1 from Ad.

    class Ad {
        var postimage: String
        var publisher: String
        var timestring: String
        var timestamp = Date().timeIntervalSince1970
    
        // You can add timestamp here also if you wish
        init(postimage: String, publisher: String, timestring: String) {
            self.postimage = postimage
            self.publisher = publisher
            self.timestring = timestring
        }
    }
    
    class PostDataAd: Ad {
        // Define some custom properties
    }
    

    And if you want to append PostData to the [Ad] array, you would do the following:

    var ads: [Ad] = []
    // Replace with your values
    let postList = PostDataAd(postimage: "", publisher: "", timestring: "") 
    ads.insert(postList, at: 0)
    
    // Appending NativeAd works also
    let nativeAdd = NativeAd(postimage: "", publisher: "", timestring: "")
    ads.append(nativeAdd)