Authored by 盖剑秋

Finish new version.

Showing 32 changed files with 684 additions and 177 deletions
... ... @@ -42,6 +42,21 @@
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>1079D7FA3D132BE7139B474946A33CC1</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>2235D976B8237504922E2F90A5C4A867</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>3CBB4A0A7B8C3306DE7E8D9BAD6FBBCF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>46E114BD7E33DA00B1C3526208605F9A</key>
<dict>
<key>primary</key>
... ... @@ -77,6 +92,11 @@
<key>primary</key>
<true/>
</dict>
<key>F18CE954D2BE9B039BF57C97D6D8B799</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
... ...
... ... @@ -45,6 +45,7 @@
2E487B121D66B0A0009DBB6D /* YH_HTTPRequestOperationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E487B111D66B0A0009DBB6D /* YH_HTTPRequestOperationManager.m */; };
2E487B311D66B2FB009DBB6D /* YH_Log.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E487B301D66B2FB009DBB6D /* YH_Log.m */; };
2E4D5FC21D057C6100D508BB /* YH_RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E4D5FC11D057C6100D508BB /* YH_RootViewController.m */; };
2E57A40B1DDC415C00AD50EF /* YH_URLResponseSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E57A40A1DDC415C00AD50EF /* YH_URLResponseSerializer.m */; };
2E5F25961DD44DDD006CC85D /* M16HttpClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F25691DD44DDC006CC85D /* M16HttpClient.m */; };
2E5F25971DD44DDD006CC85D /* M16Service.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F256B1DD44DDC006CC85D /* M16Service.m */; };
2E5F25981DD44DDD006CC85D /* NSMutableArray+QueueAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F256D1DD44DDC006CC85D /* NSMutableArray+QueueAdditions.m */; };
... ... @@ -53,7 +54,6 @@
2E5F259F1DD44DDD006CC85D /* YH_BarrageTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F25791DD44DDD006CC85D /* YH_BarrageTableView.m */; };
2E5F25A01DD44DDD006CC85D /* YH_BarrageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F257B1DD44DDD006CC85D /* YH_BarrageViewController.m */; };
2E5F25A11DD44DDD006CC85D /* YH_BuyingRoadCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F257D1DD44DDD006CC85D /* YH_BuyingRoadCell.m */; };
2E5F25A21DD44DDD006CC85D /* YH_HTTPResponseSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F257F1DD44DDD006CC85D /* YH_HTTPResponseSerializer.m */; };
2E5F25A31DD44DDD006CC85D /* YH_ImageSliceService.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F25811DD44DDD006CC85D /* YH_ImageSliceService.m */; };
2E5F25A81DD44DDD006CC85D /* YHAssistant.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F258B1DD44DDD006CC85D /* YHAssistant.m */; };
2E5F25AA1DD44DDD006CC85D /* YHL_BarrageMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E5F258F1DD44DDD006CC85D /* YHL_BarrageMessageCell.m */; };
... ... @@ -241,6 +241,8 @@
2E487B301D66B2FB009DBB6D /* YH_Log.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_Log.m; sourceTree = "<group>"; };
2E4D5FC01D057C6100D508BB /* YH_RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_RootViewController.h; sourceTree = "<group>"; };
2E4D5FC11D057C6100D508BB /* YH_RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_RootViewController.m; sourceTree = "<group>"; };
2E57A4091DDC415B00AD50EF /* YH_URLResponseSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_URLResponseSerializer.h; sourceTree = "<group>"; };
2E57A40A1DDC415C00AD50EF /* YH_URLResponseSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_URLResponseSerializer.m; sourceTree = "<group>"; };
2E5F25671DD44DDC006CC85D /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = "<group>"; };
2E5F25681DD44DDC006CC85D /* M16HttpClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M16HttpClient.h; sourceTree = "<group>"; };
2E5F25691DD44DDC006CC85D /* M16HttpClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = M16HttpClient.m; sourceTree = "<group>"; };
... ... @@ -258,8 +260,6 @@
2E5F257B1DD44DDD006CC85D /* YH_BarrageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_BarrageViewController.m; sourceTree = "<group>"; };
2E5F257C1DD44DDD006CC85D /* YH_BuyingRoadCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_BuyingRoadCell.h; sourceTree = "<group>"; };
2E5F257D1DD44DDD006CC85D /* YH_BuyingRoadCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_BuyingRoadCell.m; sourceTree = "<group>"; };
2E5F257E1DD44DDD006CC85D /* YH_HTTPResponseSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_HTTPResponseSerializer.h; sourceTree = "<group>"; };
2E5F257F1DD44DDD006CC85D /* YH_HTTPResponseSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_HTTPResponseSerializer.m; sourceTree = "<group>"; };
2E5F25801DD44DDD006CC85D /* YH_ImageSliceService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YH_ImageSliceService.h; sourceTree = "<group>"; };
2E5F25811DD44DDD006CC85D /* YH_ImageSliceService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YH_ImageSliceService.m; sourceTree = "<group>"; };
2E5F258A1DD44DDD006CC85D /* YHAssistant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YHAssistant.h; sourceTree = "<group>"; };
... ... @@ -613,6 +613,8 @@
2E6A85501D18E800001A0E59 /* yoho */ = {
isa = PBXGroup;
children = (
2E57A4091DDC415B00AD50EF /* YH_URLResponseSerializer.h */,
2E57A40A1DDC415C00AD50EF /* YH_URLResponseSerializer.m */,
2E81A5651DDAD635002B8EB3 /* NSDictionary+YOHO.h */,
2E81A5661DDAD635002B8EB3 /* NSDictionary+YOHO.m */,
2E81A5621DDAD619002B8EB3 /* NSString+YOHO.h */,
... ... @@ -638,8 +640,6 @@
2E5F257B1DD44DDD006CC85D /* YH_BarrageViewController.m */,
2E5F257C1DD44DDD006CC85D /* YH_BuyingRoadCell.h */,
2E5F257D1DD44DDD006CC85D /* YH_BuyingRoadCell.m */,
2E5F257E1DD44DDD006CC85D /* YH_HTTPResponseSerializer.h */,
2E5F257F1DD44DDD006CC85D /* YH_HTTPResponseSerializer.m */,
2E5F25801DD44DDD006CC85D /* YH_ImageSliceService.h */,
2E5F25811DD44DDD006CC85D /* YH_ImageSliceService.m */,
2E5F258A1DD44DDD006CC85D /* YHAssistant.h */,
... ... @@ -1217,7 +1217,6 @@
2EB670611D19088A00E91AAE /* UIButton+WebCache.m in Sources */,
2E81A54D1DDAB7F7002B8EB3 /* YHL_Coupon.m in Sources */,
2EB670091D18EFC800E91AAE /* HPTextViewInternal.m in Sources */,
2E5F25A21DD44DDD006CC85D /* YH_HTTPResponseSerializer.m in Sources */,
2E5F25A01DD44DDD006CC85D /* YH_BarrageViewController.m in Sources */,
2E81A55E1DDAB845002B8EB3 /* NSString+LIVE.m in Sources */,
2EB66FFE1D18EF2F00E91AAE /* NSDictionary+MTLManipulationAdditions.m in Sources */,
... ... @@ -1256,6 +1255,7 @@
2E5F25971DD44DDD006CC85D /* M16Service.m in Sources */,
2EB670671D19088A00E91AAE /* UIView+WebCacheOperation.m in Sources */,
2E81A54E1DDAB7F7002B8EB3 /* YHL_Product.m in Sources */,
2E57A40B1DDC415C00AD50EF /* YH_URLResponseSerializer.m in Sources */,
2EB66FD01D18EF0800E91AAE /* UITableView+FDTemplateLayoutCellDebug.m in Sources */,
2EB66FFD1D18EF2F00E91AAE /* NSArray+MTLManipulationAdditions.m in Sources */,
2EB66FFA1D18EF2F00E91AAE /* MTLModel.m in Sources */,
... ...
... ... @@ -2,4 +2,38 @@
<Bucket
type = "0"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "YohoLive/Classes/YH_RootViewController.m"
timestampString = "500971984.315427"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "649"
endingLineNumber = "649"
landmarkName = "-channelPressed:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "YohoLive/Classes/YH_RootViewController.m"
timestampString = "500971984.315427"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "651"
endingLineNumber = "651"
landmarkName = "-channelPressed:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
... ...
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "yohobuy_icon_29.png",
... ... @@ -55,6 +65,16 @@
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "yohobuy_icon_29-1.png",
... ...
{
"images" : [
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "Default-1242@3x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"orientation" : "landscape",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "8.0",
"subtype" : "736h",
"scale" : "3x"
"scale" : "1x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "Default-750@2x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "Default@2x-1.png",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "Default@2x.png",
"filename" : "Default-568h@2x-1.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"subtype" : "retina4",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "Default-568h@2x.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "Default-1242@3x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"orientation" : "landscape",
"idiom" : "iphone",
"extent" : "full-screen",
"scale" : "1x"
"minimum-system-version" : "8.0",
"subtype" : "736h",
"scale" : "3x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "Default@2x-1.png",
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "Default-750@2x.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "Default-568h@2x-1.png",
"filename" : "Default@2x.png",
"extent" : "full-screen",
"subtype" : "retina4",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "Default-568h@2x.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "1x"
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
}
],
... ...
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "l_size_red@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "l_size_red@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ...
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
... ... @@ -43,6 +43,9 @@ typedef NS_ENUM(NSInteger, SOCKET_TAG) {
SOCKET_TAG_SendBuyingRoad = 21,//自己正在购买的路上。
SOCKET_TAG_RedPacketRecieved = 22,//收到红包,
SOCKET_TAG_NotifyEndSuccess = 99, //服务器告知推流发起结束成功
SOCKET_TAG_PushHotSale = 10001,//推送夯货,
SOCKET_TAG_PushRefresh = 10002,//推送刷新商品列表
SOCKET_TAG_PushRedPacket = 10011,//推送发红包
};
#endif /* YHL_Enums_h */
... ...
... ... @@ -7,7 +7,7 @@
//
#import <UIKit/UIKit.h>
#import "masonry.h"
#import "Masonry.h"
#import "YHL_Product.h"
@interface YHL_HotSaleTableViewCell : UITableViewCell
... ... @@ -17,7 +17,8 @@
@property (strong, nonatomic) UILabel *salePriceLable;//商品当前价格
@property (strong, nonatomic) UILabel *originalPriceLable;//商品原来价格
@property (strong, nonatomic) UIButton *addShopCartButton;
@property (strong, nonatomic) YHL_Product *currentProduct;
- (void)bindModel:(YHL_Product *)model;
@end
... ...
... ... @@ -7,18 +7,128 @@
//
#import "YHL_HotSaleTableViewCell.h"
#import "NSString+LIVE.h"
#import "UIImageView+WebCache.h"
@implementation YHL_HotSaleTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self.contentView addSubview:self.productImageView];
[self.contentView addSubview:self.productNameLable];
[self.contentView addSubview:self.salePriceLable];
[self.contentView addSubview:self.originalPriceLable];
[self layoutContentSubviews];
UIView *line = [UIView new];
line.backgroundColor = [UIColor lightGrayColor];
[self.contentView addSubview:line];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.bottom.and.right.mas_equalTo(0);
make.height.mas_equalTo(0.5);
}];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
- (void)layoutContentSubviews
{
[self.productImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(76, 102));
make.top.mas_equalTo(10);
make.left.mas_equalTo(15);
}];
[self.productNameLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.productImageView.mas_right).offset(15);
make.right.mas_equalTo(-10);
make.top.mas_equalTo(15);
}];
[self.salePriceLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(-25);
make.left.equalTo(self.productImageView.mas_right).offset(15);
}];
[self.originalPriceLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(-25);
make.left.equalTo(self.salePriceLable.mas_right).offset(10);
}];
}
- (void)bindModel:(YHL_Product *)model
{
if (![model isKindOfClass:[YHL_Product class]]) {
return;
}
_currentProduct = model;
self.productNameLable.text = model.productName;
NSString *marketPrice = model.marketPrice;//吊牌价
NSString *salesPrice = model.salesPrice;//当前价格
self.salePriceLable.text = [NSString stringWithFormat:@"¥%@",salesPrice];
if (salesPrice.floatValue != marketPrice.floatValue) {
self.originalPriceLable.hidden = NO;
NSAttributedString *originalAttString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"¥%@",model.marketPrice] attributes:@{NSStrikethroughStyleAttributeName:@(NSUnderlineStyleSingle)}];
self.originalPriceLable.attributedText = originalAttString;
} else {
self.originalPriceLable.hidden = YES;
}
NSString *picUrlString = [model.picUrl yhl_splitUrlWithWidth:@(CGRectGetWidth(self.productImageView.bounds)*kScreenScale).stringValue height:@(CGRectGetHeight(self.productImageView.bounds)*kScreenScale).stringValue];
[self.productImageView sd_setImageWithURL:[NSURL URLWithString:picUrlString]];
}
+ (CGFloat)cellForHeight
{
return 122.0f;
}
- (UIImageView *)productImageView
{
if (!_productImageView) {
_productImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 76, 102)];//76 * 102
_productImageView.userInteractionEnabled = YES;
_productImageView.backgroundColor = [UIColor lightGrayColor];
}
return _productImageView;
}
// Configure the view for the selected state
- (UILabel *)productNameLable
{
if (!_productNameLable) {
_productNameLable = [[UILabel alloc] init];
_productNameLable.numberOfLines = 2;
_productNameLable.font = [UIFont systemFontOfSize:11];
_productNameLable.textColor = [UIColor blackColor];
}
return _productNameLable;
}
- (UILabel *)salePriceLable
{
if (!_salePriceLable) {
_salePriceLable = [[UILabel alloc] init];
_salePriceLable.font = [UIFont systemFontOfSize:17];
_salePriceLable.textColor = [UIColor redColor];
}
return _salePriceLable;
}
- (UILabel *)originalPriceLable
{
if (!_originalPriceLable) {
_originalPriceLable = [[UILabel alloc] init];
_originalPriceLable.font = [UIFont systemFontOfSize:9];
_originalPriceLable.textColor = [UIColor lightGrayColor];
}
return _originalPriceLable;
}
@end
... ...
... ... @@ -7,8 +7,10 @@
//
#import "YHL_RedPacketAndHotSaleViewController.h"
#import "YHL_HotSaleTableViewCell.h"
#import "YHL_RedPacketTableViewCell.h"
@interface YHL_RedPacketAndHotSaleViewController ()
@interface YHL_RedPacketAndHotSaleViewController ()<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, assign) LiveDataType currentType;
@property (nonatomic, strong) NSArray *dataArray;
... ... @@ -17,7 +19,10 @@
@end
@implementation YHL_RedPacketAndHotSaleViewController
{
UIButton *commitButton;
NSInteger selectedIndex;
}
+ (void)showInViewController:(UIViewController *)aController withDataType:(LiveDataType)dataType andDataArray:(NSArray *)dataAry completionBlock:(void (^)(NSInteger))block {
YHL_RedPacketAndHotSaleViewController *ctl = [YHL_RedPacketAndHotSaleViewController new];
... ... @@ -33,11 +38,110 @@
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
selectedIndex = -1;
self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];
self.view.alpha = 0;
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero];
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:tableView];
tableView.delegate = self;
tableView.dataSource = self;
[tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(15);
make.right.mas_equalTo(-15);
make.bottom.mas_equalTo(-115);
make.height.mas_equalTo(380);
}];
commitButton = [UIButton buttonWithType:UIButtonTypeCustom];
[commitButton setBackgroundColor:[UIColor lightGrayColor]];
[commitButton setTitle:@"发送" forState:UIControlStateNormal];
[commitButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
commitButton.titleLabel.font = [UIFont systemFontOfSize:17];
[commitButton addTarget:self action:@selector(commitButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:commitButton];
[commitButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(15);
make.right.mas_equalTo(-15);
make.bottom.mas_equalTo(-64);
make.height.mas_equalTo(40);
}];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self tapToDismiss];
}
- (void)tapToDismiss {
[UIView animateWithDuration:0.3 animations:^{
self.view.alpha = 0;
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
[self removeFromParentViewController];
}];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView animateWithDuration:0.3 animations:^{
self.view.alpha = 1;
}];
}
- (void)commitButtonPressed {
if (selectedIndex<0) {
return;
}
if (_completionBlock) {
_completionBlock(selectedIndex);
}
[self tapToDismiss];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 122;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedIndex = indexPath.row;
[commitButton setBackgroundColor:[UIColor blackColor]];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (_currentType) {
case LiveDataTypeHotSale:
{
YHL_HotSaleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YHL_HotSaleTableViewCell"];
if (!cell) {
cell = [[YHL_HotSaleTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"YHL_HotSaleTableViewCell"];
}
[cell bindModel:_dataArray[indexPath.row]];
return cell;
}
break;
case LiveDataTypeRedPacket:
{
YHL_RedPacketTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YHL_RedPacketTableViewCell"];
if (!cell) {
cell = [[YHL_RedPacketTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"YHL_RedPacketTableViewCell"];
}
NSDictionary *dic = _dataArray[indexPath.row];
NSString *name = dic[@"type_name"];
if (name.length) {
[cell bindRedPacketName:name];
}
return cell;
}
break;
default:
break;
}
return [UITableViewCell new];
}
- (void)didReceiveMemoryWarning {
... ...
... ... @@ -10,4 +10,6 @@
@interface YHL_RedPacketTableViewCell : UITableViewCell
- (void)bindRedPacketName:(NSString *)nameStr;
@end
... ...
... ... @@ -7,14 +7,50 @@
//
#import "YHL_RedPacketTableViewCell.h"
#import "masonry.h"
@implementation YHL_RedPacketTableViewCell
{
UILabel *nameLabel;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
UIImageView *imgV = [UIImageView new];
imgV.image = [UIImage imageNamed:@"l_size_red"];
[self.contentView addSubview:imgV];
[imgV mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(76, 102));
make.top.mas_equalTo(10);
make.left.mas_equalTo(15);
}];
nameLabel = [UILabel new];
nameLabel.font = [UIFont boldSystemFontOfSize:17];
[self.contentView addSubview:nameLabel];
[nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(imgV.centerY);
make.left.mas_equalTo(106);
}];
UIView *line = [UIView new];
line.backgroundColor = [UIColor lightGrayColor];
[self.contentView addSubview:line];
[line mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.and.bottom.and.right.mas_equalTo(0);
make.height.mas_equalTo(0.5);
}];
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)bindRedPacketName:(NSString *)nameStr {
nameLabel.text = nameStr;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
... ...
... ... @@ -547,10 +547,12 @@ static NSString *const kIdentifier_live_three = @"threePicture";
[manager setHttpURLString:@"http://api.live.yoho.cn"];
return manager;
}
//api-test3.yohops.com:9999
//api.yoho.cn
+ (instancetype)apiEngine
{
YH_HttpEngine *manager = [YH_HttpEngine manager];
[manager setHttpURLString:@"http://api.yoho.cn"];
[manager setHttpURLString:@"http://api-test3.yohops.com:9999"];
return manager;
}
+ (instancetype)paymentEngine:(NSString *)hostName
... ...
... ... @@ -21,6 +21,8 @@ typedef NS_ENUM(NSInteger, PushStatus) {
@interface YH_NetworkAdapter (Live)
- (void)getRedPacketsWithRoomId:(NSString *)roomId completion:(ArrayBlock)block;
- (void)getCouponDataWithRoomId:(NSString *)roodId completion:(DictionaryBlock)finishBlock;
... ... @@ -71,4 +73,12 @@ typedef NS_ENUM(NSInteger, PushStatus) {
* @since 4.9.1
*/
- (void)getProductListDataFromSknString:(NSString *)sknString completion:(DictionaryBlock)finishBlock;
/**
通过接口发送心跳
@param roomId roomId description
*/
- (void)sendInterfaceHeartBeatWithRoomId:(NSString *)roomId;
@end
... ...
... ... @@ -96,7 +96,7 @@
- (void)getSknListDataFromRoomID:(NSString *)roomID completion:(ArrayBlock)finishBlock
{
if (IsStrEmpty(roomID)) {
BLOCK_EXEC(finishBlock, nil,[NSError new]);
BLOCK_EXEC(finishBlock, nil,[[NSError alloc] initWithDomain:@"liveDomain" code:-1000 userInfo:@{}]);
return;
}
... ... @@ -117,7 +117,7 @@
- (void)getProductListDataFromSknString:(NSString *)sknString completion:(DictionaryBlock)finishBlock
{
if (IsStrEmpty(sknString)) {
BLOCK_EXEC(finishBlock, nil,[NSError new]);
BLOCK_EXEC(finishBlock, nil,[[NSError alloc] initWithDomain:@"liveDomain" code:-1000 userInfo:@{}]);
return;
}
... ... @@ -126,7 +126,7 @@
[paramDic setObject:@"h5.product.batch" forKey:@"method"];
[paramDic setObject:@"Y" forKey:@"contain_secKill"];
[[YH_HttpEngine apiEngine] post:paramDic success:^(AFHTTPRequestOperation *operation, id responseObject) {
[[YH_HttpEngine apiEngine] get:paramDic success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *dataDic = [responseObject objectForKey:@"data"];
if ([dataDic.allKeys count]>0) {
BLOCK_EXEC(finishBlock, dataDic,nil);
... ... @@ -156,4 +156,37 @@
BLOCK_EXEC(finishBlock, nil,error);
}];
}
- (void)getRedPacketsWithRoomId:(NSString *)roomId completion:(ArrayBlock)block {
NSDictionary *params = @{
@"room_id":roomId?:@"",
};
[[YH_HttpEngine liveEngine] get:params resourcePath:@"/v1/redbag/pushbaglist" success:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([responseObject[@"code"] integerValue] == 200) {
BLOCK_EXEC(block, responseObject[@"data"],nil);
} else {
BLOCK_EXEC(block, responseObject,nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
BLOCK_EXEC(block, nil,error);
}];
}
- (void)sendInterfaceHeartBeatWithRoomId:(NSString *)roomId {
NSDictionary *params = @{
@"room_id":roomId?:@"",
};
[[YH_HttpEngine liveEngine] get:params resourcePath:@"/v1/room/keeplive" success:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([responseObject[@"code"] integerValue] == 200) {
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
}
@end
... ...
... ... @@ -27,6 +27,8 @@
#import "YH_Tool.h"
#import "YH_NetworkAdapter+Live.h"
#import "YH_LiveViewModel.h"
#import "YHL_RedPacketAndHotSaleViewController.h"
//static const NSInteger socketMaxRetryCount = 3;
... ... @@ -174,6 +176,8 @@
if (_currentChannel) {
if ([self startRtmp]) {
[YH_Tool alertMessage:@"直播开始"];
self.liveViewModel.roomId = _currentChannel.room;
[self.liveViewModel fetchCurrentRoomProductListWithCompletion:NULL];
_totalTime = _currentChannel.totalTime.integerValue;
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateInfoView) userInfo:nil repeats:YES];
[_timer fire];
... ... @@ -200,7 +204,7 @@
config.enableAutoBitrate = NO;
[_livePush setConfig:config];
_livePush.delegate = self;
// [_livePush startPreview:self.view];
[_livePush startPreview:self.view];
}
#pragma mark --sockerserviceDelegate
... ... @@ -510,7 +514,16 @@
@param sender UIButton
*/
- (void)hotSalePressed:(UIButton *)sender {
if (self.liveViewModel.productListArray.count) {
[YHL_RedPacketAndHotSaleViewController showInViewController:self withDataType:LiveDataTypeHotSale andDataArray:self.liveViewModel.productListArray completionBlock:^(NSInteger selectedIndex) {
YHL_Product *product = [self.liveViewModel.productListArray objectAtIndex:selectedIndex];
NSDictionary *param = @{@"cmd":@(SOCKET_TAG_PushHotSale),@"room":_currentChannel.room?:@"",@"skn":product.productSkn};
[self.socketService writeDataWithParams:param tag:SOCKET_TAG_PushHotSale];
}];
} else {
[YH_Tool alertMessage:@"此房间没有夯货,稍后再试"];
[self.liveViewModel fetchCurrentRoomProductListWithCompletion:NULL];
}
}
/**
... ... @@ -518,8 +531,41 @@
@param sender UIButton
*/
static BOOL redPacketInProgress;
- (void)redPacketPressed:(UIButton *)sender {
if (redPacketInProgress) {
return;
}
redPacketInProgress = YES;
[[YH_NetworkAdapter adapter] getRedPacketsWithRoomId:self.liveViewModel.roomId completion:^(NSArray *models, NSError *error) {
redPacketInProgress = NO;
if (error||!models.count) {
[YH_Tool alertMessage:@"当前房间无可用红包"];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[YHL_RedPacketAndHotSaleViewController showInViewController:self withDataType:LiveDataTypeRedPacket andDataArray:models completionBlock:^(NSInteger selectedIndex) {
/*
{
type_id: 33,
type_name: "just a test",
coupon_ids: [
"14366",
"14368"
]
}
*/
NSDictionary *dic = [models objectAtIndex:selectedIndex];
NSArray *ary = [dic objectForKey:@"coupon_ids"];
NSString *ids = @"";
if ([ary isKindOfClass:[NSArray class]]&&ary.count) {
ids = [ary componentsJoinedByString:@","];
}
NSDictionary *param = @{@"cmd":@(SOCKET_TAG_PushRedPacket),@"room":_currentChannel.room?:@"",@"couponId":ids};
[self.socketService writeDataWithParams:param tag:SOCKET_TAG_PushRedPacket];
}];
});
}
}];
}
- (void)accelleratePressed:(UIButton *)sender {
... ...
... ... @@ -115,6 +115,7 @@
@"room":MakeStringNotNil(self.room),
};
[_socket writeDataWithParams:params tag:SOCKET_TAG_HEARTBEAT];
[[YH_NetworkAdapter adapter] sendInterfaceHeartBeatWithRoomId:self.room];
_heartBeatCount = 0;
}
... ...
... ... @@ -5,7 +5,7 @@
#import "M16HttpClient.h"
#import "YH_HTTPRequestSerializer.h"
#import "YH_HTTPResponseSerializer.h"
#import "YH_URLResponseSerializer.h"
@implementation M16HttpClient
... ...
... ... @@ -75,9 +75,6 @@
{
[super viewDidLoad];
[self.view addSubview:self.barrageTableView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:)name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotification object:nil];
}
- (void)showTintView {
... ...
//
// YH_HTTPResponseSerializer.h
// Yohoboys
//
// Created by redding on 14-9-18.
// Copyright (c) 2014年 YOHO. All rights reserved.
//
#import "AFURLResponseSerialization.h"
@interface YH_HTTPResponseSerializer : AFJSONResponseSerializer
@end
//
// YH_HTTPResponseSerializer.m
// Yohoboys
//
// Created by redding on 14-9-18.
// Copyright (c) 2014年 YOHO. All rights reserved.
//
#import "YH_HTTPResponseSerializer.h"
//NSInteger const YH_HTTPResponseSuccess = 200; //成功
//NSInteger const YH_HTTPResponseNoAuthority = 400; //没有权限
//NSInteger const YH_HTTPResponseNotFound = 404; //传参或无此接口
//NSInteger const YH_HTTPResponseInternalError = 500; //程序错误
NSString * const YH_HTTPResponseSerializationErrorDomain = @"cn.yoho.error.serialization.response";
typedef NS_ENUM(NSInteger, YH_HTTPResponseStatus) {
YH_HTTPResponseStatusSuccess = 0, //成功
YH_HTTPResponseStatusFailure = 1, //失败
};
typedef NS_ENUM(NSInteger, YH_HTTPResponseCode) {
YH_HTTPResponseCodeSuccess = 200000, //成功
YH_HTTPResponseCodeNoAuthority = 400000, //没有权限
YH_HTTPResponseCodeNotFound = 404000, //传参或无此接口
YH_HTTPResponseCodeInternalError = 500000, //程序错误
};
@implementation YH_HTTPResponseSerializer
#pragma mark - AFURLResponseSerialization
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
id responseData;
id responseObject = [super responseObjectForResponse:response data:data error:error];
//获取instagram登录信息的时候特殊处理
if (responseObject && [responseObject objectForKey:@"meta"]) {
return responseObject;
}
//获取杂志列表时需要特殊处理
if (responseObject && [responseObject objectForKey:@"magazineList"]) {
return responseObject;
}
if (responseObject && [responseObject objectForKey:@"status"]) {
YH_HTTPResponseStatus status = [[responseObject objectForKey:@"status"] integerValue];
YH_HTTPResponseCode code = [[responseObject objectForKey:@"code"] integerValue];
if (status == YH_HTTPResponseStatusFailure) {
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [responseObject objectForKey:@"message"],
};
if (error) {
*error = [[NSError alloc] initWithDomain:YH_HTTPResponseSerializationErrorDomain code:code userInfo:userInfo];
}
}
else {
responseData = [responseObject objectForKey:@"data"];
}
}
return responseData;
}
@end
//
// YH_HttpResponseSerializer.h
// YH_Mall
//
// Created by jhsonzhi on 16/3/21.
// Copyright © 2016年 YOHO. All rights reserved.
//
#import "AFURLResponseSerialization.h"
@interface YH_JSONResponseSerializer : AFJSONResponseSerializer
@end
@interface YH_HTTPResponseSerializer : AFHTTPResponseSerializer
@end
\ No newline at end of file
... ...
//
// YH_HttpResponseSerializer.m
// YH_Mall
//
// Created by jhsonzhi on 16/3/21.
// Copyright © 2016年 YOHO. All rights reserved.
//
#import "YH_URLResponseSerializer.h"
#import "NSString+YOHO.h"
static NSString * const XYHResponseChecksum = @"X-YH-Response-Checksum";
static NSString * const YHResponsePrivateKey = @"fd4ad5fcsa0de589af23234ks1923ks";
@implementation YH_HTTPResponseSerializer
/**
@brief 重写父类AFHTTPResponseSerializer的校验,增加response 数据的校验,校验算法是MD5(fd4ad5fcsa0de589af23234ks1923ks:MD5(<BODY>))
http://git.dev.yoho.cn/opentech/api/wikis/auth
该方法主要针对非JSON类返回数据,目前主要用在H5页面的返回校验
@param response
@param data 返回的二进制数据
@param error
@return NO-校验失败 YES - 成功
@since 4.1.0
*/
- (BOOL)validateResponse:(NSHTTPURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
BOOL responseIsValid = [super validateResponse:response data:data error:error];
if (!responseIsValid) {
return responseIsValid;
}
NSStringEncoding stringEncoding = self.stringEncoding;
if (response.textEncodingName) {
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName);
if (encoding != kCFStringEncodingInvalidId) {
stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);
}
}
NSError *serializationError = nil;
@autoreleasepool {
NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding];
if (responseString && ![responseString isEqualToString:@" "]) {
//定制化校验返回数据的合法性
// LogInfo(@"==== JSON verify start ====>");
NSString *resultMD5 = [response.allHeaderFields objectForKey:XYHResponseChecksum];
if (resultMD5 && [resultMD5 isKindOfClass:[NSString class]]) {
NSString *transitStr = [NSString stringWithFormat:@"%@:%@",YHResponsePrivateKey,[responseString yh_md5String]];
// LogInfo(@"\nX-YH-Response-Checksum: %@ \n compute result: %@", resultMD5, [transitStr yh_md5String]);
if (NSOrderedSame != [[transitStr yh_md5String] compare:resultMD5 options:NSCaseInsensitiveSearch]) {
// LogInfo(@"X-YH-Response-Checksum ERROR!!!");
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Response validate error.", @"Response validate error."),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"Response validate error.",@"Response validate error.")
};
serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
responseIsValid = NO;
}
}
// LogInfo(@"=== JSON verify End ===<");
}
}
if (error) {
*error = serializationError;
}
return responseIsValid;
}
@end
@implementation YH_JSONResponseSerializer
/**
@brief 重写父类AFJSONResponseSerializer的校验,增加response 数据的校验,校验算法是MD5(fd4ad5fcsa0de589af23234ks1923ks:MD5(<BODY>))
http://git.dev.yoho.cn/opentech/api/wikis/auth
该方法主要针对JSON类返回数据
@param response
@param data 返回的二进制数据
@param error
@return NO-校验失败 YES - 成功
@since 4.1.0
*/
- (BOOL)validateResponse:(NSHTTPURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
BOOL responseIsValid = [super validateResponse:response data:data error:error];
if (!responseIsValid) {
return responseIsValid;
}
NSStringEncoding stringEncoding = self.stringEncoding;
if (response.textEncodingName) {
CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName);
if (encoding != kCFStringEncodingInvalidId) {
stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);
}
}
NSError *serializationError = nil;
@autoreleasepool {
NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding];
if (responseString && ![responseString isEqualToString:@" "]) {
//定制化校验返回数据的合法性
// LogInfo(@"==== JSON verify start ====>");
NSString *resultMD5 = [response.allHeaderFields objectForKey:XYHResponseChecksum];
if (resultMD5 && [resultMD5 isKindOfClass:[NSString class]]) {
NSString *transitStr = [NSString stringWithFormat:@"%@:%@",YHResponsePrivateKey,[responseString yh_md5String]];
// LogInfo(@"\nX-YH-Response-Checksum: %@ \n compute result: %@", resultMD5, [transitStr yh_md5String]);
if (NSOrderedSame != [[transitStr yh_md5String] compare:resultMD5 options:NSCaseInsensitiveSearch]) {
// LogInfo(@"X-YH-Response-Checksum ERROR!!!");
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Response validate error.", @"Response validate error."),
NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"Response validate error.",@"Response validate error.")
};
serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
responseIsValid = NO;
}
}
// LogInfo(@"=== JSON verify End ===<");
}
}
if (error) {
*error = serializationError;
}
return responseIsValid;
}
@end
... ...