美文网首页
我的腾讯新闻swift&Charles

我的腾讯新闻swift&Charles

作者: 偶尔登南山 | 来源:发表于2017-11-01 21:19 被阅读121次

    swift的版本稳定性和兼容性有了很大提升,开发效率比objective-c要高(别人说的,哈哈),苹果也力推swift的发展,未来也是苹果的主要开发语言.
    swift3.0+时候苹果SDK接口就相对稳定了,于是乎利用空闲时间自己仿照腾讯新闻,写了一个小app.主要开发语言用的纯swift,数据接口主要抓取的是腾讯新闻数据,这是后面要说网络抓包问题.
    一. 项目的主要结构
    项目主要结构分为四大块:1)新闻, 2)推荐, 3)直播, 4)我; 项目中的资源图片大都是从腾讯新闻ipa中获取
    新闻页面
    推荐页面
    直播页面
    以上页面由于和腾讯的太像,"简叔"意思在改改,大家需要的拷贝代码,自己跑起来看看吧.

    我的页面

    二 .项目的组织结构
    项目采用MVVM模式编写开发
    2.1项目组织结构

    项目组织架构

    2.2 数据获取及处理
    各层负责各层的业务处理.数据回调一般用闭包实现.网络层用的是Alarmfire,数据解析用的是SwiftyJSON

    // MARK: - 获取要闻列表
        typealias importNewsListCallBack = (_ ipormtNewsListArray:NSMutableArray)->Void
        func getImportNewsListData(callBack:@escaping importNewsListCallBack) -> Void
        {
            let URI:String = "getQQNewsUnreadList?apptype=ios&startarticleid=&__qnr=1f08e8d71890&global_info=0%7C&omgid=014f6bb2bb7c904d07aad9dcff6aabd976f1001011221e&idfa=30216CDE-F722-49CF-84A2-15EDEE3BB30E&qqnews_refpage=QNCommonListChannelVideoController&isJailbreak=0&appver=10.3.2_qqnews_5.3.7&network_type=wifi&device_model=iPhone7%2C1&omgbizid=e6034a6a2850844febd8b82c1e5dc7b29290006011250f&screen_height=736&devid=7C632112-BA40-425A-8610-780904BF2C5B&screen_scale=3&screen_width=414&store=1&activefrom=icon";
            let URLString = kHost + URI;
            print("请求地址",URLString);
            Alamofire.request(URLString, method: .post, parameters: nil, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
                switch response.result.isSuccess
                {
                case true:
                    
                    if let value = response.result.value
                    {
                        let json = JSON(value);
                        let dataArray = NSMutableArray();
                        
                        if let newsList = json["newslist"].array
                        {
                            for (subJson:JSON) in newsList
                            {
                                let importNewsModel = ETTImportNewsModel()
                                importNewsModel.title = JSON["title"].string
                                importNewsModel.thumbnails = JSON["thumbnails"].array
                                if let string = JSON["thumbnails"].array?.first?.rawString()
                                {
                                    importNewsModel.thumbnailsString = string
                                }
                                importNewsModel.thumbnails_big = JSON["thumbnails_big"].array;
                                importNewsModel.thumbnails_qqnews = JSON["thumbnails_qqnews"].array;
                                importNewsModel.thumbnails_qqnews_photo = JSON["thumbnails_qqnews_photo"].array;
                                importNewsModel.bigImage = JSON["bigImage"].array
                                importNewsModel.imagecount = JSON["imagecount"].intValue
                                if let bigString = JSON["thumbnails_qqnews_photo"].array?.first?.rawString()
                                {
                                    importNewsModel.thumbnailsBigString = bigString
                                }
                                importNewsModel.videoTotalTime = JSON["videoTotalTime"].string
                                importNewsModel.source = JSON["source"].string
                                importNewsModel.videoNum = JSON["videoNum"].intValue
                                dataArray.add(importNewsModel)
                            }
                        }
                        callBack(dataArray)
                    }
                    break
                    
                case false:
                    break
                }
            }
        }
    

    2.3 项目中用到的scrollView 上下联动
    顶部是一个scrollView,中间内容也是一个scrollVIew,中间的滚动带动上部标题的滚动;上部标题按钮的点击触发中间页面到指定页面
    初始化顶部

    // MARK: - 设置顶部titleView
        func setupTopViews() -> Void
        {
            //搜索按钮
            let searchButton = UIButton()
            searchButton.setImage(kImage(named: "search_icon_btn_black"), for: UIControlState.normal)
            searchButton.setImage(kImage(named: "night-search_icon_btn_black"), for: UIControlState.highlighted)
            searchButton.frame = CGRect(x: -10, y: 0, width: 30, height: 44)
            searchButton.addTarget(self, action: #selector(searchButtonAction(button:)), for: UIControlEvents.touchUpInside)
            self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: searchButton);
            
            //添加按钮
            let addButton = UIButton()
            addButton.setImage(kImage(named: "timeline_add_Channel_black"), for: UIControlState.normal)
            addButton.setImage(kImage(named: "night-timeline_add_Channel_white"), for: UIControlState.highlighted)
            addButton.frame = CGRect(x: 0, y: 0, width: 30, height: 44)
            addButton.addTarget(self, action: #selector(addButtonAction(button:)), for: UIControlEvents.touchUpInside)
            self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: addButton);
            
            
            let titleContentView = UIView(frame: CGRect(x: 0, y: 0, width: kScreenWidth - 30 * 2 - 30 * 2, height: 44));
            titleContentView.backgroundColor = UIColor.white;
            
            
            titleArray = NSArray(objects: "要闻","视频","北京","财经","娱乐","体育","NBA","汽车","科技","社会","军事","国际","时尚","游戏","图片","数码","电影","教育","美容","综艺","韩流","足球","宠物","政务");
            
            titleScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: titleContentView.frame.size.width, height: 44));
            titleScrollView?.contentSize = CGSize.init(width: CGFloat((titleArray.count)) * kButtonWidth, height: 0);
            titleScrollView?.isScrollEnabled = true;
            titleScrollView?.isPagingEnabled = true;
            titleScrollView?.showsHorizontalScrollIndicator = false;
            self.navigationItem.titleView = titleScrollView;
            
            lineView = UIView(frame: CGRect(x: 0, y: 42, width: kButtonWidth, height: 2));
            lineView?.backgroundColor = kLineViewBackgroundColor;
            titleScrollView?.addSubview(lineView!);
            
            buttonArray = NSMutableArray();
            
            for index in 0...(titleArray.count - 1) {
                
                let buttonX:CGFloat = CGFloat(index) * kButtonWidth;
                let buttonY:CGFloat = 0;
                let buttonWidth:CGFloat = kButtonWidth;
                let buttonHeight:CGFloat = 40.0;
                let button = UIButton(frame: CGRect(x: buttonX, y: buttonY, width: buttonWidth, height: buttonHeight));
                button.setTitle(titleArray[index] as? String, for: UIControlState.normal);
                button.setTitleColor(kSelectedButtonTitleColor, for: UIControlState.selected);
                button.setTitleColor(kNormalButtonTitleColor, for: UIControlState.normal);
                button.tag = index;
                button.addTarget(self, action: #selector(buttonAction(button:)), for: UIControlEvents.touchUpInside);
                button.titleLabel?.font = UIFont.systemFont(ofSize: kSelectedButtonTitleFontSize);
                titleScrollView?.addSubview(button);
                buttonArray.add(button);
            }
        }
    

    顶部按钮标题的事件回调

    // MARK: - 顶部titleView按钮的点击事件回调
        @objc func buttonAction(button:UIButton) -> Void
        {
            button.isSelected = true;
            let subviews = middleScrollView?.subviews[button.tag];
            middleScrollView?.contentOffset = CGPoint(x: (subviews?.frame.origin.x)!, y: (subviews?.frame.origin.y)!);
            for index in 0...(buttonArray.count - 1) {
                let tempButton:UIButton = buttonArray[index] as! UIButton;
                if tempButton.tag != button.tag
                {
                    tempButton.isSelected = false;
                }
            }
        }
    

    通过UISrcollView的代理回调方法实现联动

    // MARK: - UIScrollViewDelegate
        func scrollViewDidScroll(_ scrollView: UIScrollView)
        {
            if scrollView == middleScrollView 
            {
                let pageIndex:Int = Int(scrollView.contentOffset.x / scrollView.frame.size.width + 0.5);
                for index in 0...((buttonArray.count) - 1) {
                    
                    if index == pageIndex
                    {
                        let button:UIButton = buttonArray[index] as! UIButton;
                        button.isSelected = true;
                        button.titleLabel?.font = UIFont.systemFont(ofSize: kSelectedButtonTitleFontSize);
                        
                        UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 5.0, options: UIViewAnimationOptions.curveEaseOut, animations: {
                            
                            var lineViewFrame = self.lineView?.frame;
                            lineViewFrame?.origin.x = button.frame.origin.x;
                            self.lineView?.frame = lineViewFrame!;
                            
                            let toRight:CGFloat = button.frame.origin.x + button.frame.size.width;
                            let toLeft:CGFloat = button.frame.origin.x;
                            let minX:CGFloat = (self.titleScrollView?.contentOffset.x)!;
                            let maxX:CGFloat = (self.titleScrollView?.contentOffset.x)! + (self.titleScrollView?.frame.size.width)!;
                            if toRight > maxX
                            {
                                self.titleScrollView?.setContentOffset(CGPoint(x: self.titleScrollView!.contentOffset.x + (toRight - maxX), y: self.titleScrollView!.contentOffset.y), animated: true);
                            }
                            
                            if toLeft < minX
                            {
                                self.titleScrollView?.setContentOffset(CGPoint(x: (self.titleScrollView?.contentOffset.x)! + (toLeft - minX), y: (self.titleScrollView?.contentOffset.y)!), animated: true);
                            }
                            
                        }, completion: { (finished) in
                            
                        })
                        
                    } else
                    {
                        let button:UIButton = buttonArray[index] as! UIButton;
                        button.isSelected = false;
                        button.titleLabel?.font = UIFont.systemFont(ofSize: kNormalButtonTitleFontSize);
                    }
                }
            } else if scrollView .isKind(of: UITableView.self)
            {
                return;
            }
        }
    

    其他部分的实现大家有兴趣的可以把代码clone下拉看看

    三. 数据抓取
    项目中用到的数据都是实时抓取腾讯新闻客户端数据,之前添加了本地持久化数据,后来又把这部分移除了.所用到的工具主要是Charles,对于Charles使用教程和破解方法网上都有,这篇文章写得挺详细:http://www.jianshu.com/p/235bc6c3ca77大家可以看看

    四. 项目地址
    最后把项目分享出来供大家批评指正,欢迎交流讨论,我的QQ:284485487
    项目地址:https://github.com/waitwalker/QQNews

    相关文章

      网友评论

          本文标题:我的腾讯新闻swift&Charles

          本文链接:https://www.haomeiwen.com/subject/sdqnpxtx.html