iOS开发-博客导出工具开发教程(附带源码)

前言:

作为一名学生, 作为一名iOS开发学习者, 我个人浏览信息包括博客, 更多的选择移动终端。然而, csdn并没有现成的客户端(不过有个web版的)。

之前曾经看到一款开源的导出工具, 但是它是基于Windows平台的。导出的也仅仅是PDF格式。而且, 对于文章的导出, 需要精确URL。无法做到边浏览别导出。

另外, 我想实现的是, 可以在没有网络的情况下, 浏览自己收藏的文章。并且, 对于自己收藏的文章, 可以分类管理。

最关键的是, 对于自己的文章, 可以做一个备份。我曾经遇到过这样一件事, csdn账号密码泄漏, 使得他人登录我账号发表垃圾博文, 导致我的博客被封一天。那时候, 我的博客记录了170篇自己的学习点滴, 没有备份, 可以想像那时候我有多慌。可见, 备份自己文章的重要性。

基于以上种种原因, 这款基于iOS平台的博客导出工具应运而生。

注:

本文章正在参与2014年csdn博客大赛。如果您觉得, 对您有所帮助, 希望能投上宝贵的一票。

投票链接:http://vote.blog.csdn.net/Article/Details?articleid=31768677

具体功能:

  • 支持在线浏览csdn博客
  • 可导类型包括: 单篇文章, 专栏, 指定作者全部文章
  • 导出方式包括: (1)导出单前浏览博文/专家/专栏 (2)导出指定URL博文/专家/专栏 
  • 导出文章分类管理
  • 导出文章查询功能
  • 导出文章自动排版, 图片自适应, 可放缩

运行效果:

看到这里, 如果你只是想体验一下这个应用, 想看看源码, 那可以从我的Github中下载。另外, 第一版已经上传到App Store上去了。 正在等待审核。

https://github.com/colin1994/csdnBlog.git

如果你想了解下整体开发过程, 欢迎继续往下看。推荐下载了源码, 对照着看

你将学到:

  • 自定义启动动画
  • 网络环境判断(是否是Wi-Fi状态)
  • IOS与JavaScript的交互
  • 自定义HUD加载效果(非传统菊花)
  • UITableView列表基本操作
  • 列表关键字模糊查询
  • 图片基本操作

下面逐一进行分析。

(一) 自定义启动动画

不同与传统的修改LaunchImage来加载一个静态的图片作为我们的欢迎界面, 我这里简单的实现了图片缩放, 文字渐渐显示的效果。

相对来说, 更加美观, 我们能做的操作也更加多。

打开AppDelegate.h文件, 声明一个变量, 用于显示我们的视图。

@property (strong, nonatomic) UIImageView *splashView;

打开AppDelegate.m文件, 加入具体实现过程。

1.添加启动动画

    //添加启动动画
    [self.window makeKeyAndVisible];

    splashView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, Screen_height)];

    if ([[UIScreen mainScreen] bounds].size.height == 568)
    {
        [splashView setImage:[UIImage imageNamed:@"bgBlog-568"]];
    }
    else
    {
        [splashView setImage:[UIImage imageNamed:@"bgBlog"]];

    }

    [self.window addSubview:splashView];
    [self.window bringSubviewToFront:splashView];

    [self performSelector:@selector(scale) withObject:nil afterDelay:0.0f];
    [self performSelector:@selector(showWord) withObject:nil afterDelay:2.5f];

2.动画具体实现

-(void)scale
{
    UIImageView *logo_ = [[UIImageView alloc]initWithFrame:CGRectMake(119, 88, 82, 82)];
    logo_.image = [UIImage imageNamed:@"csdnLogo"];
    [splashView addSubview:logo_];
    [self setAnimation:logo_];
}

-(void)setAnimation:(UIImageView *)nowView
{

    [UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveLinear
                     animations:^
     {
         // 执行的动画code
         [nowView setFrame:CGRectMake(nowView.frame.origin.x- nowView.frame.size.width*0.1, nowView.frame.origin.y-nowView.frame.size.height*0.1, nowView.frame.size.width*1.2, nowView.frame.size.height*1.2)];
     }
                     completion:^(BOOL finished)
     {
         // 完成后执行code
         [nowView removeFromSuperview];
     }
     ];

}

-(void)showWord
{

    UIImageView *word_ = [[UIImageView alloc]initWithFrame:CGRectMake(75, Screen_height-100, 170, 29)];
    word_.image = [UIImage imageNamed:@"word_"];
    [splashView addSubview:word_];

    word_.alpha = 0.0;
    [UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveLinear
                     animations:^
     {
         word_.alpha = 1.0;
     }
                     completion:^(BOOL finished)
     {
         // 完成后执行code
         [NSThread sleepForTimeInterval:1.0f];
         [splashView removeFromSuperview];
     }
     ];
}

(二)网络环境判断(是否是Wi-Fi状态)

这个需要导入Wi-Fi文件夹下的Reachability.h / .m文件。 这是从苹果官方下载的。一个用来判断网络环境的文件。

我们之所以要判断是否在Wi-Fi环境下, 是因为导出文章可能使用的流量较大, 我们需要提示用户开启Wi-Fi来下载。

1.导入Reachability.h / .m文件

2.添加头文件

#import "Reachability.h"            //Wi-Fi

3.判断网络环境

    if ([Reachability reachabilityForInternetConnection].currentReachabilityStatus == ReachableViaWiFi)
    {
        //添加你想做的事情
    }

(三)IOS与JavaScript的交互

UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS中与UIWebView中的网页元素交互。

常见的几种使用途径:

1、获取当前页面的url。

- (void)webViewDidFinishLoad:(UIWebView *)webView {
  NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
}

2、获取页面title。

- (void)webViewDidFinishLoad:(UIWebView *)webView {
   NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];

   NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];
}

3、修改界面元素的值。

NSString *js_result = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByName(‘q‘)[0].value=‘Colin‘;"];

4、表单提交:

 NSString *js_result2 = [webView stringByEvaluatingJavaScriptFromString:@"document.forms[0].submit(); "];

当然, 还有更多的功能, 需要你自己去学习。

我们这个工具所要做的是, 获取到博文的主要内容及其标题。

以导出单篇为例。

我们打开一个博文, 显示页面源代码, 可以看到下面这样的内容。

其中的"article_content" 就对应着csdn博文的正文内容. 这是我们导出过程中需要的。(你肯定也不希望导出的文章里面嵌套着广告吧...)

所以, 我们可以通过简单的两行代码获取我们需要的内容:

//获取详细内容
NSString *lJs = @"document.getElementById(\"article_content\").innerHTML";
NSString *lHtml1 = [webView stringByEvaluatingJavaScriptFromString:lJs];

同理, 文章标题可以这样获得:

//获取标题
NSString *lJs2 = @"document.getElementById(\"article_details\").getElementsByClassName(\"article_title\")[0].getElementsByTagName(\"a\")[0].innerText";
NSString *lHtml2 = [webView stringByEvaluatingJavaScriptFromString:lJs2];

再深入一点, 我们甚至可以修改显示网页的图片大小

//修改图片大小
if ([lHtml1 rangeOfString:@"<img"].location != NSNotFound)
{
        NSScanner *myScanner = [NSScanner scannerWithString:lHtml1];
        NSString *myText = nil;
        while ([myScanner isAtEnd] == NO)
        {
             [myScanner scanUpToString:@"<img" intoString:nil];
             [myScanner scanUpToString:@"s" intoString:&myText];

             lHtml1 = [lHtml1 stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@s",myText] withString:@"<img style=\"width:300px;height:this.offsetHeight;\" s"];
         }
}

(四)自定义HUD加载效果(非传统菊花)

iOS自带的加载效果是个转圈的菊花...想必大家都清楚了。

不过说实话, 那玩意确实够难看的。

选择我们要做的是, 显示一个不封闭的圈, 并且背景视图暗一点, 突出加载过程。

效果如下:

1.导入文件夹SVProgressHUD

2.添加头文件

#import "SVProgressHUD.h"           //HUD 加载显示

3.显示HUD

//显示HUD
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];

4.移除HUD

//移除HUD
[SVProgressHUD dismiss];

(五)UITableView列表基本操作

这个是基础内容了, 具体可以看blogExportedList.m这里. 有详细讲解。

这里着重介绍下左滑删除操作

1.开启运行删除模式

2.响应删除的时候, 需要做到 (1) 从列表中移除 (2)从数据中移除 (3)刷新列表

//删除
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}

/*改变删除按钮的title*/
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"删除";
}

/*删除用到的函数*/
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        //获取完整路径 以及字典和数组的初始化
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString * namePath = [documentsDirectory stringByAppendingPathComponent:@"csdnInfo.plist"];

        [blogArr removeObjectAtIndex:indexPath.row];

        [blogArr writeToFile:namePath atomically:YES];

        [nameList removeObjectAtIndex:indexPath.row];

        [myTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];  //删除对应数据的cell
    }
}

(六)列表关键字模糊查询

搜索的话, 是个很常用的功能。如果简单的关键字搜索, 想必大家都会.

但是我们需要的是模糊查询。  比如要查询  "iOS开发"  当你输入i, o开, 等等, 都能找到对应的数据。

1.导入查询字列表文件夹

2.添加头文件

//查询子列表
#import "DDList.h"
#import "PassValueDelegate.h"

3.初始化查询列表

//查询列表初始化
    nameList = [[NSMutableArray alloc]init];
    for (int i =0; i<[blogArr count]; i++)
    {
        [nameList addObject:[[blogArr objectAtIndex:i]objectForKey:@"name"]];
    }

    //初始化查询的字符串
	_searchStr = @"";

    //初始化提醒视图
	_ddList = [[DDList alloc] initWithStyle:UITableViewStylePlain];
	_ddList._delegate = self;
	[self.view addSubview:_ddList.view];
	[_ddList.view setFrame:CGRectMake(30, 108, 200, 0)];
    _ddList._totalList = nameList;

4.响应查询

具体可以看代码, 这里强调一个。 当查到数据点击的时候, 我们需要自动跳转到指定的位置。 不然查询也没用了..

//隐藏提醒视图
- (void)setDDListHidden:(BOOL)hidden
{
	NSInteger height = hidden ? 0 : 180;
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationDuration:.2];
	[_ddList.view setFrame:CGRectMake(30, 108, 200, height)];
	[UIView commitAnimations];
}

//单例,传回选中提醒框中的结果
#pragma mark -
#pragma mark 传回数据
- (void)passValue:(NSString *)value
{
    //如果有选中,则修改当前搜索内容为返回结果,调用结束函数searchBarSearchButtonClicked
	if (value)
    {
		_searchBar.text = value;
		[self searchBarSearchButtonClicked:_searchBar];
	}
	else {

	}
}

//搜索框中的字符改变时候调用
#pragma mark -
#pragma mark SearchBar Delegate Methods
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    //如果搜索框有内容,更新提示列表
	if ([searchText length] != 0) {
		_ddList._searchText = searchText;
		[_ddList updateData];
		[self setDDListHidden:NO];
	}
	else
    {
		[self setDDListHidden:YES];  //否则隐藏
	}

}

//文本框弹出,开始搜索
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
	searchBar.showsCancelButton = YES;
	for(id cc in [searchBar subviews])
    {
        if([cc isKindOfClass:[UIButton class]])
        {
            UIButton *btn = (UIButton *)cc;
            [btn setTitle:@"取消"  forState:UIControlStateNormal];
        }
    }
	return YES;
}

//开始搜索响应。
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
	searchBar.text = @"";
}

//结束文本框输入
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
	searchBar.showsCancelButton = NO;
	searchBar.text = @"";
}

//当选中了提示列表中的某个,搜索结束,选中结果,并且高亮
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
	[self setDDListHidden:YES];  //隐藏提示视图
	_searchStr = [searchBar text]; //获得查询结果
	[searchBar resignFirstResponder];  //收回键盘

    for (int i = 0; i<[blogArr count]; i++)  //从列表中查找结果,选中
    {
        if ([[[blogArr objectAtIndex:i]objectForKey:@"name"] isEqualToString:_searchStr])
        {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
            [myTableView reloadData];
            [myTableView scrollToRowAtIndexPath:indexPath     //滚动视图
                              atScrollPosition:UITableViewScrollPositionMiddle
                                      animated:YES];
            [myTableView selectRowAtIndexPath:indexPath       //选中高亮
                                    animated:YES
                              scrollPosition:UITableViewScrollPositionMiddle];
        }
    }

}

//取消搜索响应
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
	[self setDDListHidden:YES];
	[searchBar resignFirstResponder];
}

(七)图片基本操作

这里我们需要做的是, 点击一个图片, 跳转到另外一个视图, 这里视图允许对图片进行常规编辑。包括图片的缩放...

具体可以看MRZoomScrollView.h / .m这两个文件。

下面解释下实现方法。

1.添加手势。

    // Add gesture,double tap zoom imageView.
    UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                action:@selector(handleDoubleTap:)];
    [doubleTapGesture setNumberOfTapsRequired:2];
    [imageView addGestureRecognizer:doubleTapGesture];

我们的放缩都是通过手势识别来实现的。 比如, 你双指拖拉, 就是放缩。 双指点击是自动放缩, 单指点击是退出图片浏览。

2.响应手势操作

#pragma mark - Zoom methods

- (void)handleDoubleTap:(UIGestureRecognizer *)gesture
{
    float newScale = self.zoomScale * 1.5;
    CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gesture locationInView:gesture.view]];
    [self zoomToRect:zoomRect animated:YES];
}

- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
    CGRect zoomRect;
    zoomRect.size.height = self.frame.size.height / scale;
    zoomRect.size.width  = self.frame.size.width  / scale;
    zoomRect.origin.x = center.x - (zoomRect.size.width  / 2.0);
    zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
    return zoomRect;
}


至此, 这篇简单的教程就结束了。

希望, 能给您带来一点收获。

ps:

本文章正在参与2014年csdn博客大赛。如果您觉得, 对您有所帮助, 希望能投上宝贵的一票。

投票链接:http://vote.blog.csdn.net/Article/Details?articleid=31768677

学习的路上, 与君共勉。

iOS开发-博客导出工具开发教程(附带源码),布布扣,bubuko.com

时间: 2024-10-27 12:46:42

iOS开发-博客导出工具开发教程(附带源码)的相关文章

用Python编写博客导出工具

用Python编写博客导出工具 罗朝辉 (http://kesalin.github.io/) CC 许可,转载请注明出处 写在前面的话 我在 github 上用 octopress 搭建了个人博客,octopress 使用Markdown语法编写博文.之前我在CSDN博客上也写过不少的技术博文,都说自己的孩子再丑也是个宝,所以就起了把CSDN博客里面的文章导出到个人博客上的念头.刚开始想找个工具把CSDN博客导出为xml或文本,然后再把xml或文本转换为Markdown博文.可惜搜了一下现有博

CSDN博客导出工具 Mac By Swift

写这个的目的主要是用于了解Swift语言本身,以及如何与Objc和第三方框架交互 需要先使用CSDN账号来登录,可以导出所有的博客文章,添加YAML头信息的时候,会在头信息里面包含文章对应的标签和分类,以及对应的文章类型(原创.转载.翻译) 开发环境 OS X 10.10,Xcode6 Beta4,由于Beta4较之前版本对Swift更新较大,之前版本编译出报错 使用的第三方框架 AFNetworking GTM RegExCategories GitHub地址

博客园 Mac客户端 1.0 源码

直接上重点~这里是github的地址.这里是github的地址.这里是github的地址. 此次开源的是mac 1.0客户端的源码.额···也是那个不准备维护的.并且也不再维护的那个版本.之后将会对2.0的客户端进行维护. 先声明:这是我第一次用swift写osx系统软件,代码或者结构有什么问题也请大家不吝赐教,谢谢~~~ 项目结构 CNBlogsForMac从上到下目录解析: - LGWebImage  自己写的,没用到,无用的东西,可以无视.之前是想用它来做Web图片引用的,后来找到了代替的

文顶顶iOS开发博客链接整理及部分项目源代码下载

文顶顶iOS开发博客链接整理及部分项目源代码下载 网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程却很难找.如果你是初学者,在学习了斯坦福iOS7公开课和跟着文顶顶的博客做项目之后,最快只需要2个月时间,就基本可以独立完成iOS App的开发工作.有经验的开发者也可以在该博客中寻找代码片段进行学习借鉴,必有所收获. 在此也向@文顶顶 表示严重感谢! 由于文顶顶博客博文繁多,每次找文章需要频繁的翻页,

中文 iOS/Mac 开发博客列表(网址改进)

中文 iOS/Mac 开发博客列表(网址改进) https://github.com/tangqiaoboy/iOSBlogCN 大牛blog: http://blog.devtang.com/ 唐巧 网易微博后台 .猿题库.有道云笔记.粉笔网 http://beyondvincent.com/blog/archives/ 破船 http://onevcat.com/ 王巍 Line 技术领域 :ios+unity3d http://swifter.tips 王巍 swifter 的网站 htt

中文 iOS/Mac 开发博客列表

中文 iOS/Mac 开发博客列表 博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 破船之家 http://beyondvincent.com/atom.xml NSHipster http://nshipster.cn/feed.xml Limboy 无网不剩 http://feeds.feedburner.com/lzyy 唐巧的技术博客 http://blog.devtang.com/atom.xml Lex Tang http://le

iOS 游戏开发 博客

1. http://www.cnblogs.com/kesalin/archive/2012/11/10/ios_game_dev_resource.html   ( iOS游戏开发教程) 最近几天仔细了解了iOS游戏开发引擎,常用的cocos2d,Unity引擎,那么Unity是非免费的,而cocos2d则是免费开源的: 最后促使我选择cocos2d的原因有两点: 1.最重要的原因是它对应的开发工具,尤其是 “ParticleDesigner”,粒子系统编辑器,非常的喜欢(需付费$7.99美元

史上最全的iOS多媒体开发博客

这篇博客是史上最全的iOS多媒体开发博客,包括视频.音频.图片等多套API,如果要实现多媒体的功能,点进去找找有用的东西吧:http://www.cnblogs.com/kenshincui/p/4186022.html#autoid-0-0-0..

cnblogs博客下载-cnblogs博客导出-cnblogs博客备份工具-基于python

http://blog.csdn.net/infoworld/article/details/19547723 以下代码是基于infoworld的csdn备份python代码修改的cnblogs博客备份,但是和infoworld的界面不匹配,只能够用在python里面.python确实有意思,开发很快,怪不得这么流行. #! encoding=utf-8 #cnblogs博客备份,使用方法:修改最下面的url和output,然后执行就可以了. import urllib2 import re i