按照惯例, 先上效果图

前言

做这个项目是因为刚好在逛博客园的时候看到一篇文章 博客园第三方客户端-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;
}

转载于:https://www.cnblogs.com/easyToCode/p/5274410.html

iOS_CNBlog项目开发 (基于博客园api开发) 上篇相关推荐

  1. Microsoft .NET Compact Framework 开发常见问题解答 - 专注.NET技术及其相关应用开发! - 博客园...

    Microsoft .NET Compact Framework 开发常见问题解答 发布日期: 3/30/2005 | 更新日期: 3/30/2005 Microsoft .NET Compact F ...

  2. React Native开发的博客园App

    利用React Native花了大概3周的业余时间开发出这一款较完善博客园App,目前只是测试版本(v1.0.0),不过大致的功能都已经完善,如果大家有兴趣有问题可以下面反馈 安卓: 请前往 酷安ht ...

  3. python开发个人博客_[Web开发] Flask+Python 开发个人博客(一)

    最近几个月工(个)作(人)比(非)较(常)忙(懒),公众号一直没更新,但比较欣慰的是,广大测试同仁并没有抛弃我,反而关注我的人又多了很多,难道这就是传说中的春节效应? 虽说没更新,但自己也没闲着,用F ...

  4. java 安卓项目案例_Java - 随笔分类 - android开发实例 - 博客园

    随笔分类 - Java 摘要:1.使用标准输入串对象System.inSystem.in.read()一次只读入一个字节数据,而我们通常要取得一个字符串或一组数字,这就很不适合,需要其他方法取得这样的 ...

  5. android编程获取网络和wifi状态及调用网络设置界面,Android编程获取网络连接状态(3G/Wifi)及调用网络配置界面 - Android平台开发技术 - 博客园...

    获取网络连接状态 随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能. Android平台提供了ConnectivityMan ...

  6. mysql项目酒店管理博客园_项目中常用的19条MySQL优化

    在写文章之前,首先感谢 飞友科技 陆老师提供的文档.. 声明一下:下面的优化方案都是基于 " Mysql-索引-BTree类型 " 的 一.EXPLAIN 做MySQL优化,我们要 ...

  7. 基于Cordova的博客园APP

           背景: 自从今年下半年接触一个基于ReactJS 的手机APP项目.开始了解到了Corodva这个神奇的东西.后续自己也自作了一些小的APP放到了应用宝上.8月份开始想做一个博客园APP ...

  8. 博客园app小项目有源码--在百度手机助手上线

    这是一个基于博客园接口的app应用,自己花费了一段时间才完成,也算是自己第一个按照软件开发流程做的第一款比较像样子的android app应用,主要包括了: 1,需求分析 2,概要设计 3,接口分析 ...

  9. 互评Alpha版本—博客园安卓APP

    互评Alpha版本-博客园安卓APP 测评人:徐劭斌 基于NABCD评论作品 1.根据NABCD评论作品的选题:   N(Need,需求):博客园的网页版深受软件开发人员的喜爱.博客园是一个非常好的学 ...

最新文章

  1. 语义分割DeepLab v2--DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolut
  2. AJPFX关于StringBuffer类的总结
  3. SD销售订单输入成本中心
  4. AtCoder AGC009E Eternal Average (DP)
  5. 博士申请 | 加拿大Mila实验室唐建教授招收深度学习方向博士生和实习生
  6. docker搭建pxc集群
  7. 表格中建一个按钮_CAD | CAD和Excel的表格互换教程
  8. php 添加 redis 扩展模块
  9. mybatis日期范围查询_15. Django 2.1.7 模型 条件查询、模糊查询、空查询、比较查询、范围查询、日期查询...
  10. 第18章 Redis数据结构常用命令
  11. 华人、华侨、华裔之间究竟有什么区别?
  12. 三机齐发!五大全球首发的“安卓机皇”4999元起,“安卓之光” 5999元起
  13. Smoke Test Ad hoc Test
  14. PHP输出100以内的质数(包括普通写法和数组形式输出)
  15. Redis的性能瓶颈
  16. 熊猫烧香超级搞笑广告版本
  17. 让maven使用国内镜像和archetypeCatalog
  18. 有时候人们用四位数字表示一个时间,比如 1106 表示 11 点零 6 分。现在,你的程序要根据起始时间和流逝的时间计算出终止时间。 读入两个数字,第一个数字以这样的四位数字表示当前时间,第二个数字
  19. u盘显示请插磁盘f_教你自己解决U盘故障(磁盘不能打开并提示请插入磁盘)
  20. MySQL中修改ID为自增

热门文章

  1. nginx_hash表
  2. springboot中分页插件pageHelper的使用
  3. 《剑指offer》包含min函数的栈
  4. 基于mindspore的口罩检测训练与在线推理
  5. SPARK STREAMING之1:编程指南(翻译v1.4.1)
  6. 模型评估准确率、召回率、ROC曲线、AUC总结
  7. 约瑟夫环 java实现
  8. 聊聊高并发(二)结合实例说说线程封闭和背后的设计思想
  9. RDD基本转换操作:zipWithIndex、zipWithUniqueId
  10. 获取redis实例绑定cpu的情况