iOS学习之网易新闻简易Demo

时间:2022-09-22 18:09:09

简易NewsDemo代码分析

界面布局就不多说了.效果图:(自定义了三套Cell,最后一套Cell是页面最下方的"正在加载中..."Cell,图三.)

iOS学习之网易新闻简易Demo      iOS学习之网易新闻简易Demo iOS学习之网易新闻简易Demo

主要分析工程目录和流程.

iOS学习之网易新闻简易Demo

第一:Helper中的负责请求数据的网络引擎类.

网络请求类NetworkEngine主要完成数据请求的任务.用来简化控制器中的代码.将数据单独存放.

实现步骤分析:

.h文件中:

1.分析完成网络请求需要:①请求的网址 ②请求的参数 ③请求的方式(GET或者POST).

那么将这三个定义为属性.请求参数只有两种,所以定义为枚举类型.然后将请求数据和结束请求数据写成两个方法.

//
// NetworkEngine.h
// NewsDemo #import <Foundation/Foundation.h>
/**
* NetworkEngine 是网络引擎类,完成数据的网络请求操作.
*/ @class NetworkEngine;
@protocol NetworkEngineDelegate <NSObject>
//协议中添加两个方法,一个对应请求数据成功的方法,一个对应请求数据失败的方法
- (void)networkEngine:(NetworkEngine *)networkEngine requestSuccessWithData:(NSData *)data;
- (void)networkEngine:(NetworkEngine *)networkEngine requestFailWithData:(NSError *)error;
@end //请求方式(枚举类型)
typedef enum RequsetMethod {
RequsetMethodGET,
RequsetmethodPOST
}RequestMethod; @interface NetworkEngine : NSObject
@property (nonatomic, copy) NSString *linkName; //请求服务器地址
@property (nonatomic, retain) NSDictionary *parmDic; //参数字典,存储所有的请求参数.
@property (nonatomic, assign) RequestMethod requestMethod; //请求方式 @property (nonatomic, assign) id<NetworkEngineDelegate> delegate; //指定代理 //开始请求数据
- (void)startDownloadData;
//结束请求数据
- (void)stopDownloadData; @end

.m文件中:

2.有了服务器址,参数和请求方式,下面开始请求数据.但是前提是要把服务器地址装化为NSURL格式.这里就要根据请求方式来判断是否需要将参数拼接到服务器地址后面了.

GET方式的请求需要在服务器地址后,用?隔开,然后加上请求的参数.例如服务器地址为:

//API 网络接口
#define kNewsAPI @"http://m2.qiushibaike.com/article/list/text"

那么GET请求就需要加上参数变为

http://m2.qiushibaike.com/article/list/text?count=30&page=%25d&AdID=14314020462881C8509990
参数为一个字典, @{count:30,page:25,ADID:14314020462881C8509990}

下面就是判断请求方式和实现参数拼接的代码实现了,这里不详述了.

3.将服务器地址转为NSURL对象之后,下一步创建请求.由于不确定是GET还是POST,这里就用通用的创建请求方式,也是POST的请求方式

//GET创建请求方式(不可变URLRequest)
NSURLRequest *request = [NSURLRequset requestWithURL:]; //POST创建请求方式(可变MutableURLRequest)
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:];

4.如果是POST方式,还要设置请求体(就是GET方式的URL中?后面的参数)和请求方式.

[request setHTTPBody:[[self appendStringByParDic] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:@"POST"];

5.下一步创建连接对象(使用代理方式),将连接对象定义成属性,便于在结束方法中访问.

连接对象创建完毕,就可以连接服务器请求数据,(这里定义一个属性NSMutableData *mData,存储从服务器放回的所有数据.) 这里还要实现代理中的四个方法.

①:didReceiveResponse:收到服务器响应,这时候为mData开辟空间.

②:didReceiveData:开始从服务器接收数据.(一点一点传送),这时候需要进行数据拼接.

③:connectionDidFinishLoading:接收数据完毕. 关键点:这时候NetworkEngine的获取数据的工作已经完成了,它需要能够将数据发送给控制器.怎么发送呢?自然要使用代理了.

在.h文件中定义协议,并且添加方法.然后指定代理.

//协议中添加两个方法,一个对应请求数据成功的方法,一个对应请求数据失败的方法
- (void)networkEngine:(NetworkEngine *)networkEngine requestSuccessWithData:(NSData *)data;
- (void)networkEngine:(NetworkEngine *)networkEngine requestFailWithData:(NSError *)error;

并且在.m文件中的connectionDidFinishLoading方法中,给代理指定执行时机.(这本来是使用代理的最后一步,这里提前说.).

    //通知代理执行协议中请求数据成功的方法
if ([self.delegate respondsToSelector:@selector(networkEngine:requestSuccessWithData:)]) {
[self.delegate networkEngine:self requestSuccessWithData:self.mData];
}

到此,网络请求完成.

//  NetworkEngine.m
// NewsDemo #import "NetworkEngine.h" @interface NetworkEngine ()<NSURLConnectionDataDelegate>
@property (nonatomic, retain) NSURLConnection *connection; //存储连接对象
@property (nonatomic, retain) NSMutableData *mData; //存储服务器返回的所有数据
@end @implementation NetworkEngine //开始请求数据
- (void)startDownloadData {
//1.创建NSURL对象
NSURL *url = [NSURL URLWithString:[self urlString]];
//2.创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
if (self.requestMethod == RequsetmethodPOST) {
//如果是POST请求,就需要设置请求体,以及请求方式.
[request setHTTPBody:[[self appendStringByParDic] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:@"POST"];
}
//3.创建连接对象(Delegate方式)
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
} //结束请求数据
- (void)stopDownloadData {
[self.connection cancel]; //中断连接
} #pragma mark - handle
/**
* 获取网址字符串对象
*/
- (NSString *)urlString {
//保存服务器地址
NSString *newLinkName = nil;
//判断请求方式
switch (self.requestMethod) {
case RequsetMethodGET: //GET请求,需要拼接上参数
newLinkName = [self urlStringByGET];
break;
case RequsetmethodPOST: //POST请求,无需拼接
newLinkName = self.linkName;
break;
default:
break;
}
return newLinkName;
} //GET请求获取请求的网址字符串对象
- (NSString *)urlStringByGET {
//判断参数字段中是否有参数
if (!self.parmDic) {
//如果没有参数,则不需要拼接,直接返回服务器地址即可.
return self.linkName;
}
//如果有参数,则需要拼接
return [[self.linkName stringByAppendingFormat:@"?%@", [self appendStringByParDic]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
} //将字典中的所有参数拼接成字符串
- (NSString *)appendStringByParDic {
//1.创建可变数组,存储字典中的key:Value元素
NSMutableArray *tempArr = [NSMutableArray arrayWithCapacity:];
//2.遍历字典,将key:value两部分合成一个字符串对象
for (NSString *key in self.parmDic) {
NSString *newStr = [NSString stringWithFormat:@"%@=%@", key, self.parmDic[key]];
[tempArr addObject:newStr];
}
//3.将数组中的所有元素拼接成一个字符串,中间通过&间隔.
return [tempArr componentsJoinedByString:@"&"];
} #pragma mark - NSURLConnectionDataDelegate //收到服务器响应
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//开辟空间
self.mData = [NSMutableData data];
} //收到服务器数据
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//拼接数据
[self.mData appendData:data];
}
//数据传输完毕
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//通知代理执行协议中请求数据成功的方法
if ([self.delegate respondsToSelector:@selector(networkEngine:requestSuccessWithData:)]) {
[self.delegate networkEngine:self requestSuccessWithData:self.mData];
} }
//连接失败
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
//通知代理执行协议中请求数据失败的方法
if ([self.delegate respondsToSelector:@selector(networkEngine:requestFailWithData:)]) {
[self.delegate networkEngine:self requestFailWithData:error];
}
} - (void)dealloc {
[_linkName release];
[_parmDic release];
[_connection release];
[_mData release];
[super dealloc];
} @end

接下来呢?我们需要回到视图控制器中,在这里,我们会给NetworkEngine指定服务器地址和参数,让它去真正的请求数据,我们在视图控制器中接收数据并且进行解析,将解析的数据封装成一个一个Model对象存储起来,供tableView显示.

所以首先我们还是先建立Model对象吧,非常简单,我们需要让Cell显示什么数据,就在这个Model中定义什么属性,当然,也有一些东西需要注意.

1.在Models工程文件夹中建立News类

.h文件如下:

//  News.h
// NewsDemo #import <Foundation/Foundation.h>
/*
{
"template": "manual",
"hasCover": false,
"hasHead": 1,
"skipID": "54GK0096|65860",
"replyCount": 2785,
"alias": "Entertainment",
"hasImg": 1,
"digest": "",
"hasIcon": true,
"skipType": "photoset",
"cid": "C1348648351901",
"docid": "9IG74V5H00963VRO_AQ01DJ36zongssupdateDoc",
"title": "[广角镜]何炅的“老师”生涯全回顾",
"hasAD": 1,
"order": 1,
"imgextra": [
{
"imgsrc": "http://img2.cache.netease.com/3g/2015/5/19/201505191431056e75c.jpg"
},
{
"imgsrc": "http://img4.cache.netease.com/3g/2015/5/19/201505191431082bd04.jpg"
}
],
"priority": 200,
"lmodify": "2015-05-19 14:16:05",
"ename": "yule",
"tname": "娱乐",
"imgsrc": "http://img6.cache.netease.com/ent/2015/5/19/2015051914225773b5e.jpg",
"photosetID": "54GK0096|65860",
"ptime": "2015-05-19 14:16:05"
},
*/ @interface News : NSObject
@property (nonatomic, copy) NSString *title; //标题
@property (nonatomic, copy) NSString *digest; //简介
@property (nonatomic, copy) NSString *imgsrc; //图片链接
@property (nonatomic, retain) NSArray *imgextra; //另外两个图片的链接,可能有,可能没有
@property (nonatomic, assign) NSInteger flag; //用来标识当前数据需要那一套Cell来展示,如果为0,对应NewsCell,为1,对应imageCell. - (instancetype)initWithDictionary:(NSDictionary *)dic; @end

上面注释中的内容是我们从网易服务器获取到的网易新闻的新闻源数据,我们做的Demo就是基于此,由于这里我们只需要显示标题,简介,和图片,别的暂时不需要.

所以我们定义属性:标题, 简介, 左侧的图片(第一套NewsCell显示), 多图显示时候的图片(第二套ImageCell显示), 以及用来标示当前数据需要哪一套Cell显示的flag.

因为News中存储的是一条新闻的信息,所以我们还需要添加一个初始化方法,这样在视图控制器中,才能将解析出来的一个新闻数据通过初始化赋值给一个News对象.供Cell来使用,取出需要的数据.

.m文件如下:

- (instancetype)initWithDictionary:(NSDictionary *)dic {
self = [super init];
if (self) {
//KVC赋值
[self setValuesForKeysWithDictionary:dic];
//需要判断属性imgextra有没有赋值,如果赋值了,说明此时含有三张图片链接,则使用ImageCell展示.否则使用NewsCell
if (self.imgextra) {
self.flag = ; //使用ImageCell
} else {
self.flag = ; //使用NewsCell
}
}
return self;
}
//为没有对应的属性的Key实现此方法,防止程序crash
- (void)setValue:(id)value forUndefinedKey:(NSString *)key { } + (id)newsWithDictionary:(NSDictionary *)dic {
return[[[self alloc] initWithDictionary:dic] autorelease];
}

使用KVC赋值,安全起见,一定要调用一下方法,为没有对应属性的key实现此方法.

News创建完毕,回到控制器中.接上第一步,给NetworkEngine指定服务器地址和参数,让它去真正的请求数据,我们在视图控制器中接收数据并且进行解析,将解析的数据封装成一个一个Model对象存储起来,供tableView显示.

部分实现代码如下.

@interface NewsListController ()<NetworkEngineDelegate>
@property (nonatomic, retain) NSMutableArray *dataSource; //存储所有的News对象 @end @implementation NewsListController //懒加载数组
- (NSMutableArray *)dataSource {
if (!_dataSource) {
self.dataSource = [NSMutableArray arrayWithCapacity:];
}
return [[_dataSource retain] autorelease];
} //请求新闻数据
- (void)requsetData {
NetworkEngine *engine = [[NetworkEngine alloc] init];
//设置请求网址
engine.linkName = [NSString stringWithFormat:kNewsAPI, ];//0 - 20条数据
//设置请求方式
engine.requestMethod = RequsetMethodGET; //GET请求方式
//设置代理
engine.delegate = self;
//开始网络请求
[engine startDownloadData];
[engine release];
} #pragma mark - NetworkEngineDelegate
- (void)networkEngine:(NetworkEngine *)networkEngine requestSuccessWithData:(NSData *)data {
//解析数据
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
//根据Key获取存储新闻的数组
NSArray *results = dic[@"T1348648517839"];
//将数组中的每个小字典封装成NewsModel对象
for (NSDictionary *dic in results) {
News *news = [[News alloc] initWithDictionary:dic];
//添加到数组中
[self.dataSource addObject:news];
}
//让tableView刷新数据
[self.tableView reloadData]; }
- (void)networkEngine:(NetworkEngine *)networkEngine requestFailWithData:(NSError *)error { } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return ;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSUInteger count = self.dataSource.count;
return count ? count + : ; //因为有最后一个"上拉加载更多的Label",如果没有请求数据成功,那就不展示Cell.
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //如果是最后一行,则显示加载Cell
if (indexPath.row == self.dataSource.count) {
LoadingCell *cell = [tableView dequeueReusableCellWithIdentifier:kLoadingCellReuseIdentifier forIndexPath:indexPath];
return cell;
} News *news = self.dataSource[indexPath.row];
if (news.flag == ) {
//为0使用NewsCell
NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:kNewsCellReuseIdentifier forIndexPath:indexPath];
[cell configureCellWithNews:news];
return cell;
} else {
//为1,使用imageCell
ImageCell *cell = [tableView dequeueReusableCellWithIdentifier:kImageCellReuseIdentifier forIndexPath:indexPath];
[cell configureCellWithNews:news];
return cell;
} } //动态设置每一行Cell的高度
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//对于NewsCell,高度为80,ImageCell为100, loadingCell为30 //如果索引和元素个数相同,说明是最后一行
if (indexPath.row == self.dataSource.count) {
return ;
} News *news = self.dataSource[indexPath.row];
if (news.flag == ) {
return ;
} else {
return ;
}
}

分析:

第一步,肯定是请求新闻数据.给NetworkEngine设定服务器地址,参数,请求方式等.这里写成一个方法,不要忘了在viewDidLoad中调用.

既然请求了数据,我们就要接收,怎么接收呢?我们已经在NetworkEngine中定义了代理属性,就是用来传数据的,所以这里设置控制器为代理对象,并且实现协议中的方法,将接收到的数据进行解析.

//请求新闻数据
- (void)requsetData {
NetworkEngine *engine = [[NetworkEngine alloc] init];
//设置请求网址
engine.linkName = [NSString stringWithFormat:kNewsAPI, ];//0 - 20条数据
//设置请求方式
engine.requestMethod = RequsetMethodGET; //GET请求方式
//设置代理
engine.delegate = self;
//开始网络请求
[engine startDownloadData];
[engine release];
}

在协议方法中进行数据解析:(因为协议方法中传过来的是接收完毕后的数据,所以这里进行解析.)(已知为JSON数据,并且最外层为一个字典).

我们需要先定义一个属性dataSource,用来存储解析之后并封装成News对象的数据.

#pragma mark - NetworkEngineDelegate
- (void)networkEngine:(NetworkEngine *)networkEngine requestSuccessWithData:(NSData *)data {
//解析数据
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
//根据Key获取存储新闻的数组
NSArray *results = dic[@"T1348648517839"];
//将数组中的每个小字典封装成NewsModel对象
for (NSDictionary *dic in results) {
News *news = [[News alloc] initWithDictionary:dic];
//添加到数组中
[self.dataSource addObject:news];
}
//让tableView刷新数据
[self.tableView reloadData]; }

到这里,数据解析也已经完成,存储在dataSource中,剩下的工作就是让每一套Cell显示它应该显示的数据.

这里可以很方便的利用我们之前在News中定义的flag属性来进行判断.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSUInteger count = self.dataSource.count;
return count ? count + : ; //因为有最后一个"上拉加载更多的Label",如果没有请求数据成功,那就不展示Cell.
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //如果是最后一行,则显示加载Cell
if (indexPath.row == self.dataSource.count) {
LoadingCell *cell = [tableView dequeueReusableCellWithIdentifier:kLoadingCellReuseIdentifier forIndexPath:indexPath];
return cell;
} News *news = self.dataSource[indexPath.row];
if (news.flag == ) {
//为0使用NewsCell
NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:kNewsCellReuseIdentifier forIndexPath:indexPath];
[cell configureCellWithNews:news];
return cell;
} else {
//为1,使用imageCell
ImageCell *cell = [tableView dequeueReusableCellWithIdentifier:kImageCellReuseIdentifier forIndexPath:indexPath];
[cell configureCellWithNews:news];
return cell;
}
}

最后,需要说明的时是,在自定义Cell的时候,我们使用了第三方的显示图片工具EGOImageView.它为我们提供了方便的显示图片方法,直接将解析出来的NSData数据中存储的图片的NSURL显示成图片.

实例:

.h文件

#import <UIKit/UIKit.h>
#import "EGOImageView.h"
#import "News.h" @interface ImageCell : UITableViewCell
@property (nonatomic, retain) UILabel *titleLabel; //标题
@property (nonatomic, retain) EGOImageView *leftImageView;
@property (nonatomic, retain) EGOImageView *centerImageView;
@property (nonatomic, retain) EGOImageView *rightImageView; //赋值
- (void)configureCellWithNews:(News *)news;
@end .m文件
//赋值
- (void)configureCellWithNews:(News *)news {
//左边的图片
self.leftImageView.imageURL = [NSURL URLWithString:news.imgsrc];
//中间的图片
self.centerImageView.imageURL = [NSURL URLWithString:news.imgextra[][@"imgsrc"]];
//右边的图片
self.rightImageView.imageURL = [NSURL URLWithString:news.imgextra[][@"imgsrc"]];
//Title标题
self.titleLabel.text = news.title;
}

OVER.

自己还是不够熟练,不能够非常熟练的使用MVC,界面之间的数据传输是弱项,以后还要多加练习啊!

iOS学习之网易新闻简易Demo的更多相关文章

  1. iOS界面-仿网易新闻左侧抽屉式交互 续&lpar;添加新闻内容页和评论页手势&rpar;

     本文转载至  http://blog.csdn.net/totogo2010/article/details/8637430       1.介绍 有的博友看了上篇博文iOS界面-仿网易新闻左侧抽屉 ...

  2. IOS之分析网易新闻存储数据&lpar;CoreData的使用,增删改查&rpar;

    用过网易新闻客户端的朋友们都知道,获取新闻列表时有的时候他会请求网络有时候不会,查看某条新闻的时候再返回会标注已经查看的效果,接下来分析一下是如何实现的. 首先: 1.网易新闻用CoreData存储了 ...

  3. IOS开发--仿制网易新闻

    学习来源:袁峥老师的<快速集成App中顶部标题滚动条> 此次博文写的是按需求分析写代码,思路条理性杠杠的,可以提高的编码实现速度哦. 效果:   根据这个网易新闻的界面,需求分析:     ...

  4. 【转】 iOS开发 剖析网易新闻标签栏视图切换&lpar;addChildViewController属性介绍&rpar;

    原文:http://blog.csdn.net/hmt20130412/article/details/34523235 本来只是打算介绍一下addChildViewController这个方法的,正 ...

  5. iOS开发 剖析网易新闻标签栏视图切换&lpar;addChildViewController属性介绍&rpar;

    本文转载至 http://www.tuicool.com/articles/3ymMzub CSDN博客原文  http://blog.csdn.net/hmt20130412/article/det ...

  6. iOS 网易新闻用到的框架

    网易新闻iOS版在开发过程中曾经使用过的第三方开源类库.组件 1.AFNetworking AFNetworking 采用 NSURLConnection + NSOperation, 主要方便与服务 ...

  7. iOS仿网易新闻栏目拖动重排添加删除效果

    仿网易新闻栏目选择页面的基本效果,今天抽了点时间教大家如何实现UICollectionView拖动的效果! 其实实现起来并不复杂,这里只是基本的功能,没有实现细节上的修改,连UI都是丑丑的样子,随手画 ...

  8. 网易新闻iOS版使用的18个开源组件

    转载来自:http://www.jianshu.com/p/8952944f7566  原文最后编辑时间:2015.05.19 网易新闻iOS版在开发过程中曾经使用过的第三方开源类库.组件 1.AFN ...

  9. Android(java)学习笔记206:利用开源SmartImageView优化网易新闻RSS客户端

    1.我们自己编写的SmartImageView会有很多漏洞,但是我们幸运的可以在网上利用开源项目的,开源项目中有很多成熟的代码,比如SmartImageView都编写的很成熟的 国内我们经常用到htt ...

随机推荐

  1. Android 大牛的 blog 值得推荐 (转 整理)

    1 收集了 国外著名开发者 25 人,包括 Github 地址.Blog 地址以及重点贡献介绍 链接 收集了 国内部分开发者 32人,包括 Github 地址.Blog 地址以及重点贡献介绍, 链接 ...

  2. postgresql 函数 参数为复合类型

    postgresql没有存储过程,但是函数功能很强大. 在近期开发的电商管理平台中,对于产品的类目管理,设计时有个属性字段,设为字符数组,但是EF不支持数组的操作,所以在添加和修改类目时,需要对属性的 ...

  3. 正则表达式通过Unicode属性匹配

    原文链接:http://zochen.iteye.com/blog/690716 Unicode 编码并不只是为某个字符简单定义了一个编码,而且还将其进行了归类. \pP 其中的小写 p 是 prop ...

  4. Unity3D NGUI,uGUI总结

    跪求官方UI系统(2014年11月底已出,用原生的比用NGUI放心) uGUI注意点 1.要防止多个canvas叠加点击穿透,canvas里面的graphics raycaster调整到恰当选项 2. ...

  5. Arduino 3G shield using SoftwareSerial to control

    On the 3G shield, by default the power pin is on D8 and reset pin is on D9. Make it HIGH then it wor ...

  6. Java的I&sol;O总结

    概念:Java语言中数据流是接收和发送数据的管道.流是一位单项的. 流的分类: 按照字节字符:InputStream和OutputStream是字节输入输出流的抽象父类.Reader和Writer是字 ...

  7. 一颗简单的JDBC栗子

    前言:安装好数据库之后,我们编写的java程序是不能直接使用数据库的,而JDBC(Java Database Connectivity,即java数据库连接)是java语言里用来规范客户端程序访问数据 ...

  8. Django学习之十&colon; staticfile 静态文件

    目录 Django学习之十: staticfile 静态文件 理解阐述 静态文件 Django对静态文件的处理 其它方面 总结 Django学习之十: staticfile 静态文件 理解阐述     ...

  9. Asp&period;net Core应用程序部署为服务

    安装前使用dotnet命令运行下看网站能不能正常运行 1.下载nssm,下载后解压文件 下载地址:https://nssm.cc/usage 2.使用命令行工具进入到nssm的目录: 3.执行服务安装 ...

  10. LiveCharts文档-2FAQ

    原文:LiveCharts文档-2FAQ LiveCharts文档-2FAQ 原文链接 LiveCharts基于的平台有WPF,UWP,WinForms:语言是C#, FAQ: 我怎么转换一个char ...