zoukankan      html  css  js  c++  java
  • iOS_CNBlog项目开发 (基于博客园api开发) 上篇

    按照惯例, 先上效果图

    前言

    做这个项目是因为刚好在逛博客园的时候看到一篇文章 博客园第三方客户端-i博客园正式发布App Store, 这里就帮忙贴下链接吧. 

    整个项目做下来大概做了半个月, 今天算是做出1.0版本, 已经贴上github(https://github.com/samAroundGitHub/CNBlog), 欢迎各路人士指导交流啦.

    项目介绍 

    1. 工具和资料

      博客园官方open web api网址:(再次感谢桑果, 因为我不会找api...(╮(╯▽╰)╭))

    1. http://wcf.open.cnblogs.com/news/help (新闻)
    2. http://wcf.open.cnblogs.com/blog/help (博客)

      第三方框架 (这次主要想说不要用太多第三方, 所以为了开发效率只用了几个)

      1. SDWebImage
      2. MJRefresh
      3. SVProgressHUD

    2. UI设计

    这里就贴下我的一些UI杰作好了(^^)

    项目中用到的UI, 像appIcon, LaunchImage, 还有一些占位图标我是自己做的(Sketch), 然后有一部分是http://www.easyicon.net上的, 还有一部分是以前项目的图标, 我也有从ituns下载app, 打开它的包想拿它的图片, 竟然没找到想要的那几个, 应该是发网络请求获取的吧.

    不知道怎么获取app图片资源的, 这里推荐一个网址:iOS,如何模仿一个App

    开发难点

    1. 博客园api数据解析

    博客园返回的数据是xml, 所以我选择用苹果官方自带的NSXMLParser进行解析, 为此我特地写了一个工具类(SMXMLParserTool), 这里介绍一下用法, 有需要的可以拖到你的项目自己就使用.

    .h文件

    + (instancetype)sm_toolWithURLString:(NSString *)urlString nodeName:(NSString *)nodeName completeHandler:(void (^)(NSArray *contentArray, NSError *error))completerHandler;
    - (instancetype)sm_initWithURLString:(NSString *)urlString nodeName:(NSString *)nodeName completeHandler:(void (^)(NSArray *contentArray, NSError *error))completerHandler;
    
    @property (nonatomic, readonly, strong) NSArray *contentArray;
    @property (nonatomic, strong) NSString *nodeName;
    

    使用的时候只需要调用类方法, [SMXMLParserTool sm_toolWithURLString:...], 需要传入一个xml节点的名称, 比如博客园的xml节点结构如下的话,

    <doc>
    	<feed>
    		<title>博客园_48小时阅读排行</title>
    		<id>d2e2f719-12cd-414e-ac2c-9d376c950c8a;id=...</id>
    		// 刷新时间
    		<updated></updated>
    
    		<entry> </entry>
    		<entry> </entry>
    		<entry> </entry>
    	</feed>
    </doc>
    
    // 博客信息
    <entry> 
    	// 文章id
    	<id></id>
    	// 博客题目
    	<title></title>
    	// 文章概述
    	<summary></summary>
    	// 发布时间
    	<published></published>
    	// 获取时间
    	<updated></updated>
    	// 发布人信息
    	<author>
    		// 姓名
    		<name></name>
    		// 博客首页
    		<uri></uri>
    
    		<avatar>
    			// 头像
    			<http/>
    		 </avatar>
    	</author>
    
    	<link></link>
    	// 推荐人数
    	<diggs></diggs>
    	// 阅读过的人数
    	<views></views>
    	// 评论数
    	<comments></comments>
     </entry>
    

    你只要传入@"entry", 然后就会得到节点entry下以各子节点为key值为value的dictionary然后存入到contentArray, 在回调函数completeHandler中可以直接使用获得的数据contentArray. 如果解析过程发生错误, error信息会被打印到控制台.  

    2. 第二个难点还是博客园api的数据解析

    因为博客园返回博客的文章格式是html格式的. 所以需要解析html语句. 这里我采用的方法是[UIWebView LoadHtmlString:..];

    然后会发现解析完的页面图片会超出显示范围, 这是需要用到 [webView stringByEvaluatingJavaScriptFromString:..] 用javaScript改变图片大小

    // 设置图片的宽高适应屏幕
        [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:
                                                         @"var script = document.createElement('script');"
                                                         "script.type = 'text/javascript';"
                                                         "script.text = "function ResizeImages() { "
                                                         "var myImg,oldWidth,oldHeight;"
                                                         "var maxWidth=%f;"// 图片宽度
                                                         "for(i=0;i <document.images.length;i++){"
                                                         "myImg = document.images[i];"
                                                         "oldWidth = myImg.width;oldHeight = myImg.height;"
                                                         "var scale = oldWidth/oldHeight;"
                                                         "if(myImg.width > maxWidth){"
                                                         "myImg.width = maxWidth;myImg.height = maxWidth/scale;"
                                                         "}"
                                                         "}"
                                                         "}";"
                                                         "document.getElementsByTagName('head')[0].appendChild(script);", kScreenW-20]];
        [webView stringByEvaluatingJavaScriptFromString:@"ResizeImages();"];
        
    

     这样就可以把超过的图片显示到你要的范围内了.

    3. 第三个难点还是博客园api数据解析

    这次是为什么这样说呢? 因为如果你要点击webView下的图片有响应, 还得再次用到刚刚的方法 [UIWebView LoadHtmlString:..];

    默认的情况下点击是不会触发事件的, 所以要用javaScript让图片有onclick()方法, 然后改变document.loaction的值, 实现页面跳转, 在UIWebView代理方法 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; 下捕捉事件进行处理

    // 添加图片的onclick方法
        NSString *setImageOnclickString = [NSString stringWithFormat:
                                           @"function setImageOnclick() {
                                           var imgs = document.getElementsByTagName('img');
                                           for(var i=0; i<imgs.length; i++) {
                                           imgs[i].onclick = function(){
                                           document.location = this.src;}}}"];
        [webView stringByEvaluatingJavaScriptFromString:setImageOnclickString];
        [webView stringByEvaluatingJavaScriptFromString:@"setImageOnclick()"];
    

     我处理的方法是用苹果新的内嵌SFSafariViewController实现跳转, 这样的好处是直接可以在app内享有safari自带的功能, 比如保存图片, 进入阅读模式等等, 而且还是在app内没有离开你的app.  使用SFSafariViewController前需要 #import <SafariServices/SafariServices.h>

     4. 第四个难点依然是博客园api数据解析

    醉了, 是不是. 哈哈. 不过这次我说的难点是在逻辑上不是在技术上的. 获取数据的数目上下拉的获取多少数据, 总共有多少数据, 不一次性获取数据的情况下每次获取多少数据可以避免流量浪费, 反正是一系列逻辑上要解决的问题, 由于情况很多, 我就不贴代码了, 有遇到问题再交流交流.

    5. tarBarHideWhenPush

    终于第五个难点不是api数据解析了, 但是其实tarBarHideWhenPush也不算难点, 只是会经常走弯路, 当UITabBarViewController嵌套UINavgationController附加有UIViewController, 反正关系一复杂起来, 就会发现很多人问hidesBottomBarWhenPushed = YES为什么不管用, 我也百度过试过很多方法, 比如 

        self.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:.. animated:YES];
        self.hidesBottomBarWhenPushed = NO;
    

    再比如, 在viewDidappear中才加入 self.hidesBottomBarWhenPushed = YES. 反正就是很多说法, 但是都不怎么有效..

    我独门的解决方法是在你要隐藏tarBar的VC中调用

    // push后隐藏tabBar
    - (BOOL)hidesBottomBarWhenPushed {
        return YES;
    }
    

      

  • 相关阅读:
    宿主机( win 7 系统) ping 虚拟机VMware( cent os 6.6 ) 出现“请求超时”或者“无法访问目标主机”的解决方法
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/easyToCode/p/5274410.html
Copyright © 2011-2022 走看看