效果
客户端: 服务器端:
1 create table CourseVideo 2 ( 3 VideoID int IDENTITY(1,1) NOT NULL, 4 CourseID int NOT NULL, 5 VideoName varchar(500) NULL, 6 VideoPath [varchar](100) NULL, 7 VideoImage [varchar](200) NULL, 8 VideoDes [varchar](200) NULL, 9 VideoLength int NULL, 10 primary key(VideoID) 11 )
添加数据
INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (1, 1, N'数组1_为什么要使用数组.mp4', N'CourseVideo/1.mp4', N'CourseImage/1.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (2, 1, N'数组2_什么是数组', N'CourseVideo/2.mp4', N'CourseImage/2.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (3, 1, N'数组3_数组的分类及特点', N'CourseVideo/3.mp4', N'CourseImage/3.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (4, 1, N'数组4:一维数组的声明', N'CourseVideo/4.mp4', N'CourseImage/4.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (5, 1, N'数组5:一维数组的初始化', N'CourseVideo/5.mp4', N'CourseImage/5.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (6, 1, N'数组6:一维数组的访问(引用)', N'CourseVideo/6.mp4', N'CourseImage/6.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (7, 1, N'数组7:数组的算法:查找', N'CourseVideo/7.mp4', N'CourseImage/7.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (8, 1, N'数组8:数组的算法:排序 (1)', N'CourseVideo/8.mp4', N'CourseImage/8.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (9, 1, N'数组09:二维数组的声明', N'CourseVideo/9.mp4', N'CourseImage/9', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (10, 1, N'数组10:二维数组的初始化', N'CourseVideo/10.mp4', N'CourseImage/10.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (11, 1, N'数组11:二维数组的访问', N'CourseVideo/11.mp4', N'CourseImage/11.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (12, 1, N'数组12:多维数组简介', N'CourseVideo/12.mp4', N'CourseImage/12.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (13, 1, N'数组13:C语言中的字符串', N'CourseVideo/13.mp4', N'CourseImage/13.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (14, 1, N'数组14:字符数组', N'CourseVideo/14.mp4', N'CourseImage/14.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (15, 1, N'数组15:字符串的输入输出', N'CourseVideo/15.mp4', N'CourseImage/15.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (16, 1, N'数组16:字符串处理函数', N'CourseVideo/16.mp4', N'CourseImage/16.jpg', NULL) GO
记得视频路径勿加中文,否则视频播放不出来
public class DatableToList { public static List<T> ConvertToList<T>(DataTable dt) where T : new() { //定义集合 List<T> ts = new List<T>(); //获得此模型的类型 Type type = typeof(T); //定义一个临时变量 string tempName = string.Empty; //便利DataTable数据行 foreach (DataRow dr in dt.Rows) { T t = new T(); //获得此模型的公共属性 PropertyInfo[] propertys = t.GetType().GetProperties(); //遍历该对象的所有属性 foreach(PropertyInfo pi in propertys) { tempName = pi.Name;//将属性名称赋值给临时变量 //检查DataTable是否包含此列(列名==对象的属性名) if (dt.Columns.Contains(tempName)) { // 判断此属性是否有Setter if (!pi.CanWrite) continue;//该属性不可写,直接跳出 //取值 object value = dr[tempName]; //如果非空,则赋给对象的属性 if (value != DBNull.Value) pi.SetValue(t, value, null); } } //对象添加到泛型集合中 ts.Add(t); } return ts; } }
CourseVideo.cs类
public class CourseVideo { private int videoID; public int VideoID { get { return videoID; } set { videoID = value; } } private int courseID; public int CourseID { get { return courseID; } set { courseID = value; } } private String videoName; public String VideoName { get { return videoName; } set { videoName = value; } } private String videoPath; public String VideoPath { get { return videoPath; } set { videoPath = value; } } private String videoImage; public String VideoImage { get { return videoImage; } set { videoImage = value; } }
private int videoLength;
public int VideoLength { get { return videoLength; } set { videoLength = value; } }
}
CourseVideoDal.cs类
查询CourseVideo表信息
这是比较简单容易理解的方式,但是字段多的话就很不实用。
//查询视频资源 public List<CourseVideo> Select() { List<CourseVideo> list = new List<CourseVideo>(); DataTable dt = new DataTable(); CourseVideo model = null; DataBase db = new DataBase(); String comstr = "select VideoID,CourseID,VideoName,VideoPath,VideoImage,VideoLength from CourseVideo"; dt = db.GetDataTable(comstr); for (int i = 0; i < dt.Rows.Count;i++ ) { model = new CourseVideo(); model.VideoID = Convert.ToInt32(dt.Rows[i][0]); model.CourseID = Convert.ToInt32(dt.Rows[i][1]); model.VideoName = dt.Rows[i][2].ToString(); model.VideoPath = dt.Rows[i][3].ToString(); model.VideoImage = dt.Rows[i][4].ToString();
model.VideoLength = Convert.ToInt32(dt.Rows[i][5]);
list.Add(model);
}
return list;
}
之前新建的DatableToList.cs类文件就可以用到了,使用泛型将DataTable数据转换为List<T>
泛型之前一直没机会用到,于是自己百度学习了一下,封装好DatableToList文件后,很好的提高代码
了质量,更方便使用。
//使用泛型 查询视频资源 public List<CourseVideo> Select2() { List<CourseVideo> list = new List<CourseVideo>(); DataTable dt = new DataTable(); DataBase db = new DataBase(); String comstr = "select VideoID,CourseID,VideoName,VideoPath,VideoImage,VideoLength from CourseVideo"; dt = db.GetDataTable(comstr); list = DatableToList.ConvertToList<CourseVideo>(dt); return list; }
只需要在App_Code文件夹下找到Service.cs添加
添加命名空间:
using System.Web.Script.Services;
using System.Web.Script.Serialization;
还有在方法前面声明
[WebMethod(Description = "json查询视频资源")]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[WebMethod(Description = "json查询视频资源")] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public String VideoSelect() { return new JavaScriptSerializer().Serialize(courseVideoDal.Select()); // return dal.Select(); }
[WebMethod(Description = "xml查询视频资源")] public List<CourseVideo> xmlVideoSelect() { return courseVideoDal.Select(); }
设置外部访问需要在Web.config添加节点:
<webServices> <protocols> <add name="HttpSoap" /> <add name="HttpPost" /> <add name="HttpGet" /> <add name="Documentation" /> </protocols> </webServices>
接下来把项目部署在IIS服务器上即可使用,如何部署我这就不多说了,可以查一下百度
Parse WSDL后稍等15秒左右出现Finish!查看导入目录
将生成的所有文件放置在wsdl2objc文件夹导入项目中
尝试编译出现错误如下:1."libxml/tree.h" file not found
解决办法:
链接libxml2.2dylib库
TARGETS -> Build Phases -> Linking Binary With Libraries-> libxml2.2dylib
TARGETS -> Build Settings -> Search Paths-> Header Search Paths,设置“/usr/include/libxml2”
TARGETS -> Build Phases -> Compile Sources 将Service.m,USAddition.m,NSDate+ISO8601Unparsing.m,NSDate+ISO8601Parsing.m
文件 设置不使用ARC -fno-objc-arc
手动ARC设置方法如下:
1.在Compiler Flags一列加上-fno-objc-arc就表示禁止这个.m文件的ARC
2.在Compiler Flags一列加上-fobjc-arc就表示开启这个.m文件的ARC
//视频ID @property (assign,nonatomic) int ID; //视频名称 @property (copy,nonatomic) NSString *name; //视频长度 @property (assign,nonatomic) int length; //视频图片 @property (copy,nonatomic) NSString *image; //视频链接 @property (copy,nonatomic) NSString *url; + (instancetype)videoWithDict:(NSDictionary *)dict;
+(instancetype)videoWithDict:(NSDictionary *)dict { lmjVideo *video = [[self alloc] init]; video.name = dict[@"VideoName"]; video.image = dict[@"VideoImage"]; video.url = dict[@"VideoPath"]; video.length = [dict[@"VideoLength"] intValue]; video.ID = [dict[@"VideoID"] intValue]; return video; // [video setValuesForKeysWithDictionary:dict]; // KVC方法使用前提: 字典中的所有key 都能在 模型属性 中找到 }
自定义cell,对cell内部数据处理的封装
文件
@class lmjVideo; @interface lmjVideoCell : UITableViewCell @property (nonatomic,strong) lmjVideo *video; + (instancetype)cellWithTableView:(UITableView *)tableView;
#import "lmjVideoCell.h" #import "lmjVideo.h" #import "UIImageView+WebCache.h" #import "UIView+Extension.h" @interface lmjVideoCell() @property (nonatomic,weak) UIView *driver; @end @implementation lmjVideoCell + (instancetype)cellWithTableView:(UITableView *)tableView { static NSString *ID = @"video"; lmjVideoCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (!cell) { cell = [[lmjVideoCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } return cell; } - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { UIView *driver = [[UIView alloc] init]; driver.backgroundColor = [UIColor lightGrayColor]; driver.alpha = 0.2; [self.contentView addSubview:driver]; self.driver = driver; } return self; } - (void)setVideo:(lmjVideo *)video { _video = video; self.textLabel.text = video.name; self.detailTextLabel.text = [NSString stringWithFormat:@"时长:%d分钟",video.length]; NSString *imageUrl = [NSString stringWithFormat:@"http://180.84.33.156:8882/%@",video.image]; [self.imageView setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"placeholder"]]; } - (void)layoutSubviews { [super layoutSubviews]; //调整子控件的frame CGFloat imageX = 10; CGFloat imageY = 10; CGFloat imageH = self.height - 2 * imageY; CGFloat imageW = imageH * 200 / 112; self.imageView.frame = CGRectMake(imageX, imageY, imageW, imageH); self.textLabel.x = CGRectGetMaxX(self.imageView.frame) + 10; self.detailTextLabel.x = self.textLabel.x; CGFloat driverH = 1; CGFloat driverY = self.height - driverH; CGFloat driverW = self.width; self.driver.frame = CGRectMake(0, driverY, driverW, driverH); }
分类
UIView+Extension.h文件
添加一个UIView的分类,直接修改UI控件的x值
@property (nonatomic,assign) CGFloat x;
@property (nonatomic,assign) CGFloat y;
@property (nonatomic,assign) CGFloat width;
@property (nonatomic,assign) CGFloat height;
UIView+Extension.m文件
#import "UIView+Extension.h" @implementation UIView (Extension) - (void)setX:(CGFloat)x { CGRect frame = self.frame; frame.origin.x = x; self.frame = frame; } - (CGFloat)x { return self.frame.origin.x; } - (void)setY:(CGFloat)y { CGRect frame = self.frame; frame.origin.y = y; self.frame = frame; } - (CGFloat)y { return self.frame.origin.y; } - (void)setWidth:(CGFloat)width { CGRect frame = self.frame; frame.size.width = width; self.frame = frame; } - (CGFloat)width { return self.frame.size.width; } - (void)setHeight:(CGFloat)height { CGRect frame = self.frame; frame.size.height = height; self.frame = frame; }
- (CGFloat)height { return self.frame.size.height; } @end
实现“视屏列表界面只支持竖屏方向
自定义lmjNavigationController控制器,其继承自UINavigationController
UIInterfaceOrientationMaskPortrait:竖屏(正常) UIInterfaceOrientationMaskPortraitUpsideDown:竖屏(上下颠倒) UIInterfaceOrientationMaskLandscapeLeft:横屏向左 UIInterfaceOrientationMaskLandscapeRight:横屏向右 UIInterfaceOrientationMaskLandscape:横屏(左右都支持) UIInterfaceOrientationMaskAll:所有都支持
#import "lmjNavigationViewController.h" @interface lmjNavigationViewController () @end @implementation lmjNavigationViewController //控制当前控制器支持那些方向 -(NSUInteger)supportedInterfaceOrientations {
//竖屏 return UIInterfaceOrientationMaskPortrait; } @end
导入MediaPlayer.framework框架,lmjMoviePlayerViewController.h在添加头文件
#import <MediaPlayer/MediaPlayer.h>
lmjMoviePlayerViewController.m
#import "lmjMoviePlayerViewController.h" @interface lmjMoviePlayerViewController () @end @implementation lmjMoviePlayerViewController - (void)viewDidLoad { [super viewDidLoad]; // 移除程序进入后台的通知 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; } #pragma mark - 实现这个方法来控制屏幕方向 /** * 控制当前控制器支持哪些方向 * 返回值是UIInterfaceOrientationMask* */ - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; }
@end
需要注意的是,视频播放的文件路径勿加中文,否则视频不能播放
// // lmjViewController.m // 橙子视频客户端 // // Created by lmj on 15-6-24. // Copyright (c) 2015年 lmj. All rights reserved. // #import "lmjViewController.h" #import "MBProgressHUD+MJ.h" #import "lmjVideo.h" #import "UIImageView+WebCache.h" #import "lmjMoviePlayerViewController.h" #import "lmjVideoCell.h" #import "Service.h" #define strUrl @"http://180.84.33.156:8882" @interface lmjViewController () //所有视频的集合 @property (nonatomic,strong) NSArray *videos; @end @implementation lmjViewController - (void)viewDidLoad { [super viewDidLoad]; [MBProgressHUD showMessage:@"正在加载视频信息..."]; NSString *result; NSData *data; ServiceSoap *binding = [Service ServiceSoap]; Service_VideoSelect *request = [[Service_VideoSelect alloc] init]; ServiceSoap12Response *response = [binding VideoSelectUsingParameters:request]; for(id mine in response.bodyParts){ if([mine isKindOfClass:[Service_VideoSelectResponse class]]) { // [request release]; [MBProgressHUD hideHUD]; result = [mine VideoSelectResult]; data = [result dataUsingEncoding:NSUTF8StringEncoding]; if(data) { // NSLog(@"data----%@",data); NSArray *array =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSMutableArray *videos = [NSMutableArray array]; for (NSDictionary *dict in array) { lmjVideo *video = [lmjVideo videoWithDict:dict]; [videos addObject:video]; NSLog(@"%@",video.url); } self.videos = videos; [self.tableView reloadData]; } else{ [MBProgressHUD showError:@"网络繁忙"]; } // NSLog(@"ns----%@",ns); // NSDictionary *dict= [NSJSONSerialization JSONbjectWithData:data options:NSJSONReadingAllowFragmentS error:nil]; } } } #pragma mark -数据源 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.videos.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { lmjVideoCell *cell = [lmjVideoCell cellWithTableView:tableView]; cell.video = self.videos[indexPath.row]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 70; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { lmjVideo *video = self.videos[indexPath.row]; //播放视频 NSLog(@"%@",video.url); NSString *videoUrl = [NSString stringWithFormat:@"http://180.84.33.156:8882/%@",video.url]; lmjMoviePlayerViewController *playerVc = [[lmjMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:videoUrl]]; [self presentMoviePlayerViewControllerAnimated:playerVc] ; //全拼播放 } @end