0%

苹果开发者账号区别与申请

针对所有 Apple 平台进行开发从未如此简单。要开始为 iOS、OS X 和 watchOS 开发 app ,请从 Mac App Store 下载 Xcode。如果您已准备好分发 app、实现高级 app 功能以及下载最新的测试版 OS,Apple Developer Program 会向您提供所需的任何内容,以供您制作 app 并将它们分发给全球各地的 Apple 客户。

个人

Apple Developer Program

如果您是个人或代表独资/个人企业并有意创建 app 在适用于 iPhone、iPad、Mac 和 Apple Watch 的 App Store 上分发,请注册 Apple Developer Program。会员资格包括以下内容的使用权限:测试版 OS、高级 app 功能,以及用于开发、测试和分发 app 和 Safari Extensions 的工具。作为个人注册的开发者将使用个人姓名在 App Store 上销售 app。

企业

Apple Developer Program

如果您代表组织并有意创建 app 在适用于 iPhone、iPad、Mac 和 Apple Watch 的 App Store 上分发,请注册 Apple Developer Program。会员资格包括您的整个开发团队对以下内容的使用权限:测试版 OS、高级 app 功能以及开发、测试和分发 app 和 Safari Extensions 所需的工具。组织将使用自己的法定实体名称销售 app。在注册过程中,公司和教育机构必须提供注册其法定实体时的 D-U-N-S 编号(可免费获取)

Apple Developer Enterprise Program

如果您的组织想要创建专门设计的 app 并只将其分发给您组织的员工,请注册 Apple Developer Enterprise Program。会员资格包括您的整个开发团队对以下内容的使用权限:测试版 OS、高级 app 功能以及开发、测试和分发 app 所需的工具。在注册过程中,公司和教育机构必须提供注册其法定实体时的 D-U-N-S 编号(可免费获取)。

总结

个人账号申请简单,通过很快,申请周期为一两天左右就可以通过。申请费用为每年99美元。每个账号每年可以绑定最多100台设备进行测试。个人账号可以发布App到App Store。

邓氏编码(D-U-N-S®Number) 邓白氏专有的9位数字全球编码系统,被广泛应用于企业识别和商业信息的组织及整理,可以帮助您识别和迅速定位全球超过2亿家企业的信息。

企业账号申请开发者账号前要先去申请公司的D-U-N-S编码(邓白氏编码)。申请D-U-N-S编码周期时间较长。大约需要一个月左右的审核时间。申请到D-U-N-S编码后,就可以申请企业开发者账号。申请周期3-5天左右。企业账号有两种:

  • Apple Developer Program和个人账号功能相似。可以发布App到App Store。可以绑定设备100台。费用为每年99美元。

  • Apple Developer Enterprise Program不可以发布App到App Store,App只针对企业内部使用,绑定设备数量没有限制。申请费用为每年299美元。

一般企业申请99美元的Apple Developer Program企业账号就可以了。

注意

申请时付款需要VISA或MasterCard信用卡,不支持国内的银联卡

申请D-U-N-S Number时间比较久。尽量提前申请,申请过程中,可以申请加急,多个苹果客服打电话。可以加快申请进度

iOS基础系列之#pragma和#warning使用

#pragma 避开了注释和代码之间的界限。作为预处理指令,#pragma 在编译时进行计算。但它并不像如 #ifdef…#endif 之类的宏,#pragma 的使用方式不会改变你的应用运行时的行为。相反的,#pragma 声明主要由 Xcode 用来完成两个主要任务:整理代码和防止编译器警告。

Xcode默认支持了将#waring标记以编译警告的形式显示出来

整理代码

使用#pragma mark -来整理你的代码。
其实最主要的是用来进行标记的,当然也有注释的作用在里面。当然我们也可以用//,/* */等常用注释来说明。但是用#pragma mark -不同的是可以将整个文件的函数以类似分组的形式展现。当我们点击Xcode 导航栏上面的文件后面的列表时将会得到清晰地结构。

Xcode默认支持了将#waring标记以编译警告的形式显示出来。
灵活使用#warning可以提升你的开发效率

防止警告

#pragma mark十分主流。另一方面,用#pragma声明来防止来自编译器或者静态分析器的警告现在还是很新鲜的。

你知道有什么是比有糟糕的格式的代码更烦人的吗?生成警告的代码。 尤其是第三方的代码。一个供应库要花很长时间来编译,终于成功编译时却生成了200+警告这种事实在很烦人。

提示:试试设置-Weverything标志,并在你的build setting里选择“Treat Warnings as Errors”。这将会开启Xcode的困难模式

参考文章:

iOS清除代码警告

iOS中的预编译指令

#pragma

php-mediainfo获得的信息解析

数据解析

直接看代码就好了
一层一层解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
require 'vendor/autoload.php';
use Mhor\MediaInfo\MediaInfo;
$mediaInfo = new MediaInfo( );

//获得视频信息
$mediaInfoContainer = $mediaInfo->getInfo('test.mpg');
//转换成json格式
$jsonData = json_encode($mediaInfoContainer);
//对json格式解码
$jsonDecodeData = json_decode($jsonData);

/**********************************************************************************************************/
//最外层的解析 主要有用的是$general、$audios、$videos其他的信息这里用不到
//版本
$version = $jsonDecodeData->version;
//整体信息
$general = $jsonDecodeData->general;
//音频信息
$audiosZ = $jsonDecodeData->audios;
$audios = $audiosZ[0];
//视频信息
$videosZ = $jsonDecodeData->videos;
$videos = $videosZ[0];
//字幕信息
$subtitles = $jsonDecodeData->subtitles;
//图片
$images = $jsonDecodeData->images;
//菜单
$menus = $jsonDecodeData->menus;
//其他
$others = $jsonDecodeData->others;

/*********************************************************/
//Version不需要再解析 $version这里就是当前的版本信息
/*********************************************************/
//$general的解析
//
//视频格式列表
$video_format_list = $general->video_format_list;
//视频解编码器
$codecs_video = $general->codecs_video;
//音频格式列表
$audio_format_list = $general->audio_format_list;
//音频解编码器
$audio_codecs = $general->audio_codecs;
//完整名字
$complete_name = $general->complete_name;
//文件名
$file_name = $general->file_name;
//文件格式
$file_extension = $general->file_extension;
//格式
$format = $general->format->shortName;
//网络媒体类型
$internet_media_type = $general->internet_media_type;
//解编码器
$codec = $general->codec->shortName;
//文件大小 单位bit
$file_size = $general->file_size->bit;
//持续时间 单位毫秒
$duration = $general->duration->milliseconds;
//总比特率模式
$overall_bit_rate_mode = $general->overall_bit_rate_mode->shortName;
//总比特率
$overall_bit_rate = $general->overall_bit_rate->shortName;
//帧率
$frame_rate = $general->frame_rate->absoluteValue;

var_dump($codec);
/*********************************************************/
//$audios的解析
//音频格式
$Audio_format = $audios->format->shortName;
//音频网络媒体类型
$Audio_internet_media_type = $audios->internet_media_type;
//音频解编码器
$Audio_codec = $audios->codec->shortName;
//音频比特率模式
$Audio_bit_rate_mode = $audios->bit_rate_mode->shortName;
//音频比特率 单位bps
$Audio_bit_rate = $audios->bit_rate->absoluteValue;
//声道
$Audio_channel_s = $audios->channel_s->absoluteValue;
//音频采样率
$Audio_sampling_rate = $audios->sampling_rate->absoluteValue;
//音频采样数
$Audio_frame_count = $audios->frame_count;
//音频压缩模式
$Audio_compression_mode = $audios->compression_mode->shortName;

/***********************************************************/
//$videos的解析
//视频格式
$Video_format = $videos->format->shortName;
//视频格式版本
$Video_format_version = $videos->format_version;
//视频格式简介
$Video_format_profile = $videos->format_profile;
//视频格式设置 BVOP GOP 这些东西都不是很了解
$Video_format_settings = $videos->format_settings;
//视频格式设置矩阵
$Video_format_settings_matrix = $videos->format_settings_matrix;
//视频网络媒体类型
$Video_internet_media_type = $videos->internet_media_type;
//视频解编码器
$Video_codec = $videos->codec->shortName;
//视频解编码profile
$Video_codec_profile = $videos->codec_profile;
//视频比特率
$Video_bit_rate = $videos->bit_rate->absoluteValue;
//视频最大比特率
$Video_maximum_bit_rate = $videos->maximum_bit_rate->absoluteValue;
//视频宽度 单位像素
$Video_width = $videos->width->absoluteValue;
//视频高度 单位像素
$Video_height = $videos->height->absoluteValue;
//像素宽高比
$Video_pixel_aspect_ratio = $videos->pixel_aspect_ratio;
//显示宽高比 16:9 4:3--
$Video_display_aspect_ratio = $videos->display_aspect_ratio->absoluteValue;
//视频帧率
$Video_frame_rate = $videos->frame_rate;
//视频比色法
$Video_colorimetry = $videos->colorimetry;
//视频色彩空间
$Video_color_space = $videos->color_space;
//视频色度抽样
$Video_chroma_subsampling = $videos->chroma_subsampling;
//视频位深度
$Video_bit_depth = $videos->bit_depth;
//视频扫描类型
$Video_scan_type = $videos->scan_type->shortName;
//视频压缩模式
$Video_compression_mode = $videos->compression_mode->shortName;
//视频流大小 单位 bit
$Video_stream_size = $videos->stream_size->bit;

php-MediaInfo


需求描述

获取一个视频文件的详细信息

实现方法

安装MediaInfo

  • linux下安装方法终端下执行

    $ sudo apt-get install mediainfo

  • Mac下安装方法终端下执行

    $ brew install mediainfo

  • Mac下有相应的MediaInfo的GUI版本

安装相应的开源框架

这次用的是GitHub上开源框架php-mediainfo

  1. 集成这个开源框架到你的项目中

    • 使用Composer将php-mediainfo安装到你的项目中。

    • 局部安装Composer安装命令如下(先要进到你的项目目录下在执行安装命令)

      curl -sS https://getcomposer.org/installer | php

    • 使用Composer安装php-mediainfo到你的项目(也要在你的项目目录下去执行)

      $ php composer.phar require mhor/php-mediainfo

      等待安装结束后再项目中就可以使用php-mediainfo。


  1. 使用php-mediainfo
1
2
3
4
5
6
7
8
9
require 'vendor/autoload.php';
use Mhor\MediaInfo\MediaInfo;
$mediaInfo = new MediaInfo( );
//获得视频信息
$mediaInfoContainer = $mediaInfo->getInfo('test.mpg');
//转换成json格式
$jsonData = json_encode($mediaInfoContainer);
//对json格式解码
$jsonDecodeData = json_decode($jsonData);

$mediaInfoContainer保存了”yanshi.mp4”这个文件详细的信息。
$json只是为了方便查看内容。将信息转换成json格式后放到json解析网站查看结构解析自己需要的信息。
更多的使用方法查看php-mediainfo的github仓库的readme文件。

参考资料

MongoDB的基本使用

安装过程这里不再详细解释参考:

菜鸟教程

其实这里面已经很详细的讲解了MongoDB从安装到使用的过程。我这里只是记录一下,我在做一个项目的时候用到的简单的知识。

在linux平台下首先在终端输入mongo进入到mongo的shell命令下,之后就可以对数据库进行一系列的操作了。


输入help命令后,可以查看一些操作。

常用命令:

  • show dbs 显示数据库列表
  • show collections 显示当前数据库中的集合(类似关系数据库中的表)
  • show users 显示用户
  • use <db name> 切换当前数据库
  • db.help() 显示数据库操作命令,里面有很多的命令
  • db.<CollectionsName>.help() 显示集合操作命令,同样有很多的命令,foo指的是当前数据库下,一个叫foo的集合,并非真正意义上的命令
  • db. <CollectionsName>.find() 对于当前数据库中的foo集合进行数据查找(由于没有条件,会列出所有数据)

更多的东西暂时还没用到所有也没有系统的去学习MongoDB,我这里要用到php去操作MongoDB,后面应该会再记录一下php操作MongoDB的基本使用。

提供一些参考资料

Swift语法新特性——guard

与if语句相同的是,guard也是基于一个表达式的布尔值去判断一段代码是否该被执行。与if语句不同的是,guard只有在条件不满足的时候才会执行这段代码。你可以把guard近似的看做是Assert,但是你可以优雅的退出而非崩溃。
从下面的例子中就可以看出guard的优美之处,不再用很多嵌套的if else 知道了guard语法后,代码的可读性变强。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//if else
func buy( money: Int , price: Int , capacity: Int , volume: Int){

if money >= price{
if capacity >= volume{
print("I can buy it!")
print("\(money-price) Yuan left.")
print("\(capacity-volume) cubic meters left")
}
else{
print("No enough capacity")
}
}
else{
print("Not enough money")
}
}

//guard guard 只有在不满足条件的情况下才会执行括号中的内容,这样就可更专注于符合的逻辑,增强可读性
func buy2( money: Int , price: Int , capacity: Int , volume: Int){

guard money >= price else{
print("Not enough money")
return
}

guard capacity >= volume else{
print("Not enough capacity")
return
}
print("I can buy it")
print("\(money-price) Yuan left.")
print("\(capacity-volume) cubic meters left")
}

let money = 100
let price = 170

let capacity = 50
let volume = 20

buy( money, price: price, capacity: capacity, volume: volume)
buy2( money, price: price, capacity: capacity, volume: volume)

开发遇到问题总结

后台线程更新UI问题

  • 场景描述:使用socket连接获取数据,将数据存入数组,每当收到一条是数据的时候,解析数据、添加到数据同时更新tableview中的数据。tableview的dataSource为这个数组。
  • 遇到的问题:数据更新了但是Tableview中的数据要滑动一下tableview才能同步数据
  • 原因分析:socket连接是异步的,更新UI是要在主线程的。所以把更新UI的方法添加到主线程即可。就是把reloadData方法添加到主线程。

UITableView高度问题

  • 固定高度的时候使用self.tableView.rowHeight = 88
    不要使用UITableViewDelegate中的
1
2
3
4
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return xxx
}
  • 使用第二个方法设置高度的时候,rowHeight属性会失效。一般情况下,用第一种方法去实现固定高度。第二种方法实现,多种Cell的高度。

  • 需要计算高度的时候是有第三方框架

参考文章:

优化UITableViewCell高度计算的那些事

UITableView-FDTemplateLayoutCell - GitHub链接


label自适应宽高一级cell的自适应宽高

  • 需求如下:label根据内容自适应宽度,label根据内容自适应高度。cell根据label自适应高度。
  • 实现代码
  • 结合另一篇文章
    label自适应高度可以实现cell自适应。也可以使用第三方框架。
1
2
3
4
5
6
7
8
cell.userName.text =   [NSString stringWithFormat:@"%@ : ", _dataArray1[indexPath.row][@"userName"]];
cell.barrageContent.text = _dataArray1[indexPath.row][@"message"];
CGFloat width = [UILabel getWidthWithTitle:cell.userName.text font:cell.userName.font];
CGFloat userNameHeigth = [UILabel getHeightByWidth:width title:cell.userName.text font:cell.userName.font];
CGFloat height = [UILabel getHeightByWidth:200 title:cell.barrageContent.text font:cell.barrageContent.font];
cell.userName.frame = CGRectMake(5, 0, width, userNameHeigth);
cell.barrageContent.frame = CGRectMake(5+5+cell.userName.frame.size.width, 0, 200, height);
_barrageView.rowHeight = height;

JsonKit报错

一个是ARC问题 添加 -fno-obj-arc

另外一个是JsonKit在64位机器上出现Crash的问题
原因:内存溢出
解决办法:因为JsonKit太久没有更新还是使用MRC所有尽量不要在使用JsonKit换其他框架
已经用了的解决办法:下载这个人的JsonKit替换掉原来的JsonKit就好了。

Label属性介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//创建Label
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 40)];

//设置Label的Text
label.text = @"这是Label的Text";

//设置文字颜色
label.textColor = [UIColor redColor];

//设置Label的字体
label.font = [UIFont systemFontOfSize:20];//系统默认字体
label.font = [UIFont boldSystemFontOfSize:20];//系统默认加粗字体
label.font = [UIFont italicSystemFontOfSize:20];//系统默认倾斜字体
label.font = [UIFont fontWithName:@"Arial" size:20];//设置字体类型和大小

//设置Label的对其方式
label.textAlignment = NSTextAlignmentCenter;//居中对齐
label.textAlignment = NSTextAlignmentRight;
label.textAlignment = NSTextAlignmentLeft;

//设置label显示的行数
label.numberOfLines = 0;//设置0代表自动换行

//高亮
label.highlighted = YES;
label.highlightedTextColor = [UIColor blueColor];

//设置阴影颜色与偏移量
[label setShadowColor:[UIColor purpleColor]];
[label setShadowOffset:CGSizeMake(-1, -1)];


/**
* adjustsFontSizeToFitWidth设置为YES来控制文本基线行为
* UIBaselineAdjustmentAlignBaselines = 0,默认,文本最上端与中线对齐。
UIBaselineAdjustmentAlignCenters, 文本中线与label中线对齐。
UIBaselineAdjustmentNone, 文本最低端与label中线对齐。
*/
label.adjustsFontSizeToFitWidth = YES;
label.baselineAdjustment = UIBaselineAdjustmentNone;

//设置字体大小适应label宽度
label.adjustsFontSizeToFitWidth = YES;

//设置边框,所有UIView控件都有下面的属性都可用同样的方法设置
label.layer.borderColor = [[UIColor redColor]CGColor];
label.layer.borderWidth = 2.0;
label.layer.masksToBounds = YES;
label.layer.cornerRadius = 10;

Label自适应高度与自适应宽度

创建一个Category。

新建file->Objective—C File->下一步

File Type选择:Category

Class :UILabel

下一步。

在.h文件中添加两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 传入字符串,字体自动计算宽度
*
* @param title 字符串
* @param font 字体
*
* @return 返回宽度
*/
+ (CGFloat)getWidthWithTitle:(NSString *)title font:(UIFont *)font;

/**
* 传入宽度、字符串、字体。自动计算高度
*
* @param width 宽度
* @param title 字符串
* @param font 字体
*
* @return <#return value description#>
*/
+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont*)font;

.m文件中实现相应的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font
{

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 0)];
label.text = title;
label.font = font;
label.numberOfLines = 0;
[label sizeToFit];
CGFloat height = label.frame.size.height;
return height;
}

+ (CGFloat)getWidthWithTitle:(NSString *)title font:(UIFont *)font {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 1000, 0)];
label.text = title;
label.font = font;
[label sizeToFit];
return label.frame.size.width;
}

使用方法:

这里结合的是自定义cell。

1
2
3
cell.userName.text = _dataArray1[indexPath.row];
CGFloat width = [UILabel getWidthWithTitle:cell.userName.text font:cell.userName.font];
cell.userName.frame = CGRectMake(5, 5, width, 30);

实现的效果:

两个Label连在一起,前面的Label的宽度要根据内容自适应,最后实现了想要的效果。

iOS中的五种传值方式

属性传值

场景:正向传值,界面A push 到界面B。把A中的值传递给B

使用:只需要在界面B的头文件声明属性,在A中初始化B的实例后,直接给B的实例的属性赋值。就可以实现A的值传给B

1、在B的.h文件中声明属性(userName和userAge就是你要从A中获得的值)

1
2
@property (nonatomic, copy)NSString *userName;
@property (nonatomic, copy)NSString *userAge;

2、在A中push到B前的时候给B的实例的属性赋值。(_userName就是A中的值,把这个值赋值给B的属性)

1
2
3
4
5
//初始化一个实例,给实例中的属性赋值,这样就实现了OneVC的值传递给TwoVC
TwoViewController *vc = [[TwoViewController alloc]init];
vc.userName = _userName;
vc.userAge = _userAge;
[self.navigationController pushViewController:vc animated:YES];

总结
使用简单,只能是在正向传值的场景中使用。


代理传值

场景:逆向传值,A push到 B ,B pop回 A ,把B的值传递给A。

使用:

1、在B(.h文件)中声明协议、和协议方法

1
2
3
4
5
//协议的命名规范:类名+delegate
@protocol DelegateTwoViewControllerDelegate <NSObject>
//将要传的值作为协议方法的参数
- (void)getString:(NSString *)string;
@end

2、添加代理人属性(在B的.h文件中)

1
2
3
@interface DelegateTwoViewController : UIViewController
@property (nonatomic,weak) id<DelegateTwoViewControllerDelegate> delegate;
@end

3、让代理人执行协议方法(在B的.m文件中)这里_textfiled.text就是要传递给A的值

1
2
3
4
5
//这一步一般是在B跳转到A的方法中实现的,我是在B中创建了一个Button,让这个通知代理在Button中跳转方法中实现。
if ([self.delegate respondsToSelector:@selector(getString:)]) {
// 加入if语句就是先判断在界面A中是否有getStrin这个方法,当有这个方法的时候,才进行代理传值。
[self.delegate getString:_textfiled.text];
}

4、A遵守协议(在A的.m文件中)

1
@interface DelegateOneViewController ()<DelegateTwoViewControllerDelegate>

5、指定代理人(在A的.m文件中)

1
2
3
4
5
- (void)pushEvent{
DelegateTwoViewController *vc = [[DelegateTwoViewController alloc]init];
vc.delegate = self;
[self.navigationController pushViewController:vc animated:YES];
}

6、实现协议方法(在A的.m文件中)这里的string就是从B中传来的值

1
2
3
- (void)getString:(NSString *)string{
_label.text = string;
}