无法从" self"获取数据从swift iOS中的协议扩展的类中的关键字?

时间:2018-03-07 08:15:30

标签: ios swift

我的问题是我无法从ViewController中的self获取数据。在调试时,我看到了自己的数据。但我无法得到它。

我试过了self.presenterD.lBEveryOneData[0]

我收到此错误Value of type 'LeaderBoardPresenterP' has no member 'lBEveryOneData'

这是' self'关键字。 Data in self keyword

这是LeaderBoardPresenter协议。

    protocol LeaderBoardPresenterP : class {
    var currentTimePeriod : Int {get}
    var currentSegment : Int { get}
    var numberOfTeam : Int{ get }
    var numberOfRowForEveryOne : Int{ get }

    func viewDidLoad()
    func viewDidAppear()
    func viewWillAppear()
    func tabBarBtnTap(index : Int)
    func segmentBtnTap(index : Int)
    func numberOfRowInTeam(section : Int)->(Int)
    func configureHeaderView(leaderBoardHeaderView : LeaderBoardHeaderView, section : Int)
    func configureTeamCell(cell : LeaderBoardTeamCell, indexPath : IndexPath)
    func configureEveryOneCell(cell : LeaderBoardEveryOneCell, row : Int)
    func performForLeaderBoardRefresh(successHandler: @escaping(Bool)->(), errorHandler : @escaping()->())
}

这是LeaderBoardPresenter实施

class LeaderBoardPresenterImplimentation : LeaderBoardPresenterP {


fileprivate weak var leaderViewD : LeaderBoardViewP?
fileprivate var time = 2
fileprivate var segment = 4
fileprivate var lBEveryOneData          = Array<LeaderBoardModel>()
fileprivate var lBTeamData   = Array<Array<LeaderBoardModel>>()

init(leaderBoardVC : LeaderBoardViewP) {
    self.leaderViewD = leaderBoardVC
}

//MARK:- LeaderBoardPresenterP

var numberOfTeam : Int{
    return lBTeamData.count
}

var currentTimePeriod : Int {
    return time
}
var currentSegment : Int{
    return segment
}

var numberOfRowForEveryOne : Int{
    return self.lBEveryOneData.count
}

func viewDidLoad()
{
    leaderViewD?.setUpOnViewDidLoad()
}

func viewWillAppear()
{
    leaderViewD?.setUpOnViewWillAppear()
}

func viewDidAppear()
{
    LeaderBoardManager.sharedManager.getLeaderBoardDataRequest(successHandler: { _ in
        self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
            self.leaderViewD?.reloadList(isData: isSuccess)
            self.leaderViewD?.showHideProgressView(false)
        })
    }, errorHandler: { errorString in
        self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
            self.leaderViewD?.reloadList(isData: isSuccess)
            self.leaderViewD?.showHideProgressView(false)
        })
    })
    leaderViewD?.setUpOnViewDidAppear()
}

func numberOfRowInTeam(section : Int)->(Int)
{
    return lBTeamData[section].count
}

func tabBarBtnTap(index : Int)
{
    self.time = index
    self.leaderViewD?.updateTabBarButton()
    self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
        self.leaderViewD?.reloadList(isData: isSuccess)
        self.leaderViewD?.showHideProgressView(false)
    })
}

func segmentBtnTap(index: Int) {
    self.segment = index
    var isData = false
    if self.segment == 4
    {
        isData = self.lBEveryOneData.count > 0 ? true : false
    }
    else
    {
        isData = self.lBTeamData.count > 0 ? true : false
    }
    self.leaderViewD?.reloadList(isData : isData)
}

func configureEveryOneCell(cell : LeaderBoardEveryOneCell, row : Int)
{
    let lbM = lBEveryOneData[row]
    let name = lbM.firstName + " " + lbM.lastName
    cell.displayName(name: name)
    cell.displayScore(score: lbM.totalScore.usFormat())
    cell.displayPicture(url: lbM.profileImageUrl, defaultImage: "LB_default_user")
    cell.displaySubManager(subManager: lbM.teamName)
    cell.displayRank(rank: lbM.rank)
}

func configureTeamCell(cell : LeaderBoardTeamCell, indexPath : IndexPath)
{
    let lbM = lBTeamData[indexPath.section][indexPath.row]
    let name = lbM.firstName + " " + lbM.lastName
    cell.displayName(name: name)
    cell.displayScore(score: lbM.totalScore.usFormat())
    cell.displayPicture(url: lbM.profileImageUrl, defaultImage: "LB_default_user")
    cell.displayRank(rank: indexPath.row + 1)
}

func configureHeaderView(leaderBoardHeaderView : LeaderBoardHeaderView, section : Int)
{
    let lbM = lBTeamData[section][0]
    let headerTitle = lbM.teamName
    leaderBoardHeaderView.displayTitle(headerTitle: headerTitle)
}

func performForLeaderBoardRefresh(successHandler: @escaping(Bool) -> (), errorHandler: @escaping () -> ()) {
    LeaderBoardManager.sharedManager.getLeaderBoardDataRequest(successHandler: { _ in
        self.buildLeaderBoardDataSet(complitionHandler: { (isSuccess) in
            self.leaderViewD?.reloadList(isData: isSuccess)
            self.leaderViewD?.showHideProgressView(false)
            successHandler(isSuccess)
        })
    }, errorHandler: { errorString in
        //self.leaderViewD?.reloadList(isData: isSuccess)
        self.leaderViewD?.showHideProgressView(false)
        errorHandler()
    })
}

//MARK:- Private Method

fileprivate func buildLeaderBoardDataSet(complitionHandler : @escaping (Bool)->())
{
    leaderViewD?.showHideProgressView(true)
    self.getLeaderBoardDataFromDBAndCreateSet(successHandler: { (isSuccess) in
        complitionHandler(isSuccess)
    })
}
fileprivate func getLeaderBoardDataFromDBAndCreateSet(successHandler : @escaping (Bool)->())
{
    var type = ""
    switch self.currentTimePeriod {
    case 1:
        type = "thisWeek"
        break
    case 2:
        type = "thisMonth"
        break
    case 3:
        type = "overAll"
        break
    default:
        break
    }
    LeaderBoardManager.sharedManager.retriveLeaderBoard(type) { (response, success) in
        if((response) != nil) {
            self.lBEveryOneData = response!
            self.createGroupDataSet(lbArr: response!)
            successHandler(true)
        }else{
            successHandler(false)
        }
    }
}

fileprivate func createGroupDataSet(lbArr : Array<LeaderBoardModel>)
{
    if lbArr.count > 0 {
        var keyArr = [(Int, String, Int, String)]()
        for temp in lbArr
        {
            let temp1 = temp
            keyArr.append((temp1.teamId , temp1.teamName, 0, ""))
        }

        var keySetArr = [(Int, String, Int, String)]()
        for item in keyArr {
            if !keySetArr.contains(where:{$0 == item})
            {
                keySetArr.append(item)
            }
        }
        let sortedKeySet = keySetArr.sorted(by: { (a0, a1) -> Bool in
            return a0.1.localizedCaseInsensitiveCompare(a1.1) == ComparisonResult.orderedAscending
        })

        self.lBTeamData.removeAll()

        for item in sortedKeySet
        {
                var leaderBoardDataArr = lBEveryOneData as Array<LeaderBoardModel>

                leaderBoardDataArr = leaderBoardDataArr.filter({ (leaderBoardM) -> Bool in
                    leaderBoardM.teamId == item.0
                })
                leaderBoardDataArr = leaderBoardDataArr.sorted(by: { (lb1, lb2) -> Bool in
                    lb1.totalScore > lb2.totalScore
                })
                if(leaderBoardDataArr.count > 0)
                {
                    lBTeamData.append(leaderBoardDataArr.map{
                        $0.copy() as! LeaderBoardModel})
                }
        }
    }
}

这是LeaderBoardVC。

import Foundation

class LeaderBoardVC : UIViewController, UIScrollViewDelegate, UITableViewDataSource, UITableViewDelegate, LeaderBoardViewP {

var configurator : LeaderBoardConfiguratorP!
var presenterD : LeaderBoardPresenterP!

//MARK:- Outlets
@IBOutlet weak var contentView      : UIView!
@IBOutlet weak var topScrollView    : UIView!
@IBOutlet weak var bottomScroll     : UIScrollView!
@IBOutlet weak var leaderBoardTV    : UITableView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!

@IBOutlet weak var noRecordL    : UILabel!
@IBOutlet weak var everyOneBtn  : UIButton!
@IBOutlet weak var teamBtn      : UIButton!
@IBOutlet weak var weekBtn      : UIButton!
@IBOutlet weak var monthBtn     : UIButton!
@IBOutlet weak var allTimeBtn   : UIButton!

//MARK:- Life cycle
override func viewDidLoad() {
    super.viewDidLoad()
    configurator.configure(leaderBoardVC: self)
    presenterD.viewDidLoad()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    presenterD.viewWillAppear()
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    presenterD.viewDidAppear()

    //Download leaderBoard data from server
    self.showHideProgressView(true)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    AppDelegate.getSharedInstance().isShowingChallengOnScreen = false
}

//MARK:- Action

@IBAction func tabBarBtnAction(sender : UIButton) {
    presenterD.tabBarBtnTap(index: sender.tag)
}

@IBAction func segmentBtnAction(sender : UIButton) {
    presenterD.segmentBtnTap(index: sender.tag)
    var seletedbutton : UIButton!
    var unSeletedbutton : UIButton!
    if(sender.tag == 4)
    {
        seletedbutton  = everyOneBtn
        unSeletedbutton = teamBtn
    }
    else if(sender.tag == 5)
    {
        seletedbutton  = teamBtn
        unSeletedbutton = everyOneBtn
    }
    seletedbutton.setTitleColor(UIColor.white, for: UIControlState.normal)
    seletedbutton.backgroundColor = kFYNavigationBarColor
    seletedbutton.layer.cornerRadius = 8.0

    unSeletedbutton.setTitleColor(kFYNavigationBarBelowColor, for: UIControlState.normal)
    unSeletedbutton.backgroundColor = UIColor.clear
    unSeletedbutton.layer.cornerRadius = 0.0
}

//MARK:- LeaderBoardView

func setUpOnViewDidLoad()
{
    self.navigationController!.navigationBar.topItem!.title = ""
    self.navigationItem.title = "LEADERBOARD"

    //Add refresh control on tableview
    let refreshControl: UIRefreshControl = {
        let refreshControl = UIRefreshControl()
        refreshControl.tintColor = kFYNavigationBarColor
        refreshControl.addTarget(self, action: #selector(self.refreshAction(refreshControl:)), for: UIControlEvents.valueChanged)
        return refreshControl
    }()
    self.leaderBoardTV.addSubview(refreshControl)
}

func setUpOnViewWillAppear()
{
    bottomScroll.contentSize.width = self.view.frame.size.width * 3
    self.showNoRecordView(isShow: false)
}

func setUpOnViewWillDisappear()
{

}

func setUpOnViewDidAppear()
{

}

func updateTabBarButton()
{
    DispatchQueue.main.async {

        let x = CGFloat(self.presenterD.currentTimePeriod - 1) * self.bottomScroll.frame.width

        UIView.animate(withDuration: TimeInterval(kFYZeroFractionThreeVar), animations: {

            self.bottomScroll.setContentOffset(CGPoint(x: x, y: 0), animated: false)
            self.contentView.frame.origin.x = x
            self.weekBtn.alpha = 0.7
            self.monthBtn.alpha = 0.7
            self.allTimeBtn.alpha = 0.7
            self.weekBtn.layer.borderWidth = 0
            self.monthBtn.layer.borderWidth = 0
            self.allTimeBtn.layer.borderWidth = 0

            (self.topScrollView.viewWithTag(self.presenterD.currentTimePeriod) as! UIButton).alpha = 1.0
            (self.topScrollView.viewWithTag(self.presenterD.currentTimePeriod) as! UIButton).layer.borderWidth = 1.0

        }, completion:{(value: Bool) in
            print("xyz\(self.contentView.frame)")
            self.contentView.frame.origin.x = x
            //            self.bottomScroll.contentOffset.x = self.contentView.frame.origin.x
            //            self.contentView.frame.origin.x = self.bottomScroll.bounds.size.width * CGFloat(self.presenterD.currentTimePeriod)
            //            self.contentView.frame  = CGRect(x: self.bottomScroll.bounds.size.width * CGFloat(self.presenterD.currentTimePeriod), y: 0, width: self.contentView.bounds.size.width, height: self.contentView.bounds.size.height)
        })
    }
}

/**
 This will show or hide progress view on screen

 - Parameter isShow: bool value to perform show/hide

 */
func showHideProgressView( _ isShow :Bool)
{
    DispatchQueue.main.async {
        if(isShow)
        {
            self.activityIndicator.startAnimating()
            self.view.isUserInteractionEnabled = !isShow;

        }
        else
        {
            self.activityIndicator.stopAnimating()
            self.view.isUserInteractionEnabled = !isShow;
        }
    }
}

func reloadList(isData : Bool)
{
    DispatchQueue.main.async {
        self.showNoRecordView(isShow: false)
        self.leaderBoardTV.reloadData()
    }
}

//MARK:- TableView Data Source
func numberOfSections(in tableView: UITableView) -> Int
{
    if presenterD.currentSegment == 4
    {
        return 1
    }
    else
    {
        return presenterD.numberOfTeam
    }
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if presenterD.currentSegment == 4
    {
        return presenterD.numberOfRowForEveryOne
    }
    else
    {
        return presenterD.numberOfRowInTeam(section : section)
    }

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if(presenterD.currentSegment == 4)
    {
        let everyOneCell = tableView.dequeueReusableCell(withIdentifier: "LeaderBoardEveryOneCell")! as! LeaderBoardEveryOneCell
        presenterD.configureEveryOneCell(cell: everyOneCell, row: indexPath.row)
        print(self.presenterD.lBEveryOneData[0])
        return everyOneCell

    }
    else
    {
        let teamCell = tableView.dequeueReusableCell(withIdentifier: "LeaderBoardTeamCell")! as! LeaderBoardTeamCell
        presenterD.configureTeamCell(cell: teamCell, indexPath: indexPath)
        return teamCell
    }
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
    if(presenterD.currentSegment == 5)
    {
        let view : LeaderBoardHeaderView = LeaderBoardHeaderView.instanceFromNib()
        presenterD.configureHeaderView(leaderBoardHeaderView: view, section: section)
        return view
    }
    else
    {
        return nil
    }
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
    if(presenterD.currentSegment == 5)
    {
        return 30.0
    }
    else
    {
        return 0.0
    }
}

//MARK:- Other private method

fileprivate func showNoRecordView(isShow : Bool)
{
    DispatchQueue.main.async {
        if isShow
        {
            self.noRecordL.alpha = 1
            self.contentView.alpha = 0
        }
        else
        {
            self.noRecordL.alpha = 0
            self.contentView.alpha = 1
        }
    }
}

/**
 Called when user refresh the leader board table

 - Parameter refreshControl: sender object

 */
@objc fileprivate func refreshAction(refreshControl : UIRefreshControl)
{
    DispatchQueue.main.async {
        self.view.isUserInteractionEnabled = false
        refreshControl.beginRefreshing()
    }
    presenterD.performForLeaderBoardRefresh(successHandler: { isSuccess in
        DispatchQueue.main.async {
            refreshControl.endRefreshing()
            self.view.isUserInteractionEnabled = true
            self.reloadList(isData: isSuccess)
        }
    }, errorHandler: {
        DispatchQueue.main.async {
            refreshControl.endRefreshing()
            self.view.isUserInteractionEnabled = true
        }
    })
}

}

1 个答案:

答案 0 :(得分:2)

这里的问题很简单。 presenterD变量的类型为LeaderBoardPresenterP,而不是其实现LeaderBoardPresenterImplimentation。但是,lBEveryOneData属性在LeaderBoardPresenterImplimentation中定义,而不在LeaderBoardPresenterP协议中定义。因此,从类型系统的角度来看,presenterD没有lBEveryOneData属性(尽管变量引用的真实对象具有此属性)。

使其可访问的一种方法是将该属性添加到协议(我猜你更喜欢):

protocol LeaderBoardPresenterP : class {

    // one way to make it accessible is to declare that property in the protocol:
    var lBEveryOneData: Array<LeaderBoardModel> { get set }

    var currentTimePeriod : Int {get}
    var currentSegment : Int { get}
    var numberOfTeam : Int{ get }
    var numberOfRowForEveryOne : Int{ get }

    func viewDidLoad()
    func viewDidAppear()
    func viewWillAppear()
    func tabBarBtnTap(index : Int)
    func segmentBtnTap(index : Int)
    func numberOfRowInTeam(section : Int)->(Int)
    func configureHeaderView(leaderBoardHeaderView : LeaderBoardHeaderView, section : Int)
    func configureTeamCell(cell : LeaderBoardTeamCell, indexPath : IndexPath)
    func configureEveryOneCell(cell : LeaderBoardEveryOneCell, row : Int)
    func performForLeaderBoardRefresh(successHandler: @escaping(Bool)->(), errorHandler : @escaping()->())
}

另一种方法是将presenterD的类型从LeaderBoardPresenterP类型更改为LeaderBoardPresenterImplimentation - 但这会破坏协议的目的。