iOS 10.3 应用内更换应用图标的方法

更换图标需要支持以下几点:

1、首先需要确保手机系统是否在10.3以上

2、是否支持更换应用图标

具体代码如下:
if #available(iOS 10.3, *) {
guard UIApplication.shared.supportsAlternateIcons else {
return
}
UIApplication.shared.setAlternateIconName("yellow_logo", completionHandler: { (error) in
if error != nil {
print("没成功")
}
})
}

其次还需要设置Info.plist

接着将logo拖入项目文件中。最终效果如下

null

时光胶囊-遇到另外一个你

想保存的回忆、心情不好时的涂鸦、鼓励未来自己的话语、写给未来的一句话,一张照片,一个故事。一次回忆,一次失落,一次喜悦,一次计划都可以写在这个小小胶囊里,埋藏起来,当你所约定好的那天来临的一刻你会收到当年埋下的那个小小胶囊,那时的你的心情又会是怎样的呢?感兴趣的话就来埋下一个试试吧

下载地址:https://itunes.apple.com/cn/app/id1208421351

碎片知识 (1)

1、开发者证书无效:
遇到这种情况需要下载苹果最新证书
然后在钥匙串->显示->显示过期证书下,删除过期的原证书即可,这样就没问题了
2、iOS9 设备上http网页无法加载:
需要在plist里面设置:NSAppTransportSecurity里面的”Allow Arbitrary Loads”这个属性为true。
其次如果想只添加单独网页需要用:Exception Domains这个参数来添加,如下图:
piece 01
其中的属性为:NSIncludesSubdomains(子域名是否也可以加载)、NSExceptionRequiresForwardSecrecy(是否禁用ForwardSecrecy)、NSExceptionAllowInsecureHTTPLoads(是否允许签名过期,或者不匹配等情况)
3、Bitcode:
默认项目是开启的,Bitcode可以帮助App减小包的大小,但有的第三方库不支持,所以凭项目情况来决定是否开启
4、企业App无法安装:
这个是因为iOS9 需要在设置->通用->描述文件中开启信任即可
5、iOS9 字体显示不全:
可以使用:sLabel.sizeToFit() 或者 sizeWithAttributes 来自动拉伸
6、iOS9 无法跳其他App:
需要在plist添加字段:LSApplicationQueriesSchemes,然后在其下面添加要跳转的App scheme

SFSafariViewController

SFSafariViewController 也是iOS9之后,苹果推出的新功能,这个框架使用起来相对比UIWebView简单一些。但是目前感觉仅适用于简单操作,因为SFSafariViewController只提供了两个实例化方法,两个delegate方法。
接下来我们简单看下如何使用这个新框架吧。
首先需要包含框架
[code lang=”Objective-C”]import SafariServices[/code]
其次就是实例化,并跳入到控制器
[code lang=”Objective-C”]// entersReaderIfAvailable参数是是否可以调用阅读模式
let safarivc = SFSafariViewController(URL: NSURL(string: “http://www.baidu.com”)!, entersReaderIfAvailable: true)
self.presentViewController(safarivc, animated: true, completion: nil)[/code]
接下来实现SFSafariViewControllerDelegate
[code lang=”Objective-C”]// 此方式是打开safari加载网页完成之后的方法,打印结果显示是否加载成功
func safariViewController(controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
print(“\(didLoadSuccessfully)”)
}
// 点击完成后调用此方法
func safariViewControllerDidFinish(controller: SFSafariViewController) {
print(“back”)
}
// 点击分享按钮就能拦截到此方法,在这里可以自定义分享里面的按钮
func safariViewController(controller: SFSafariViewController, activityItemsForURL URL: NSURL, title: String?) -> [UIActivity] {

print(“\(URL),\(title)”)

let ac = UIActivity()
return [ac]
}[/code]
以上就是SFSafariViewController 控制器的简单集成

Replay Kit 使用

Replay Kit 感觉是玩游戏时需要的,可以录制视频,可以语言教学。但是要求在iOS9以上,那么我们来看看如何简单的集成这个框架进行录制自己的小视频吧。
首先需要包含框架

import ReplayKit

其次就是创建一个按钮,来供我们进行录制功能,然后方法名为startRecording

func startRecording(sender :UIButton) {
    if RPScreenRecorder.sharedRecorder().available {
        // true :第一个参数代表是否开启麦克风
        RPScreenRecorder.sharedRecorder().startRecordingWithMicrophoneEnabled(true, handler: { (error :NSError?) -> Void in
            if error == nil {
                sender.removeTarget(self, action: "startRecording:", forControlEvents: .TouchUpInside)
                sender.addTarget(self, action: "stopRecording:", forControlEvents: .TouchUpInside)
                sender.setTitle("停止", forState: .Normal)
            }else{
                print("录像失败")
            }
        })
    }else{
         print("不能录像")
    }
}

接下来我们要实现停止录像的方法

func stopRecording(sender :UIButton){
    RPScreenRecorder.sharedRecorder().stopRecordingWithHandler { (previewController : RPPreviewViewController?, error :NSError?) -> Void in
        if previewController != nil {
            previewController?.previewControllerDelegate = self
            let alertController = UIAlertController(title: "Recording", message: "Do you wish to discard or view your gameplay recording?", preferredStyle: .Alert)
            // 取消按钮
            let discardAction = UIAlertAction(title: "Discard", style: .Default) { (action: UIAlertAction) in
                RPScreenRecorder.sharedRecorder().discardRecordingWithHandler({ () -> Void in
                    // Executed once recording has successfully been discarded
                })
            }
            // 确定按钮
            let viewAction = UIAlertAction(title: "View", style: .Default, handler: { (action: UIAlertAction) -> Void in
                self.presentViewController(previewController!, animated: true, completion: nil)
            })
                
            alertController.addAction(discardAction)
            alertController.addAction(viewAction)
                
            self.presentViewController(alertController, animated: true, completion: nil)
                
            sender.removeTarget(self, action: "stopRecording:", forControlEvents: .TouchUpInside)
            sender.addTarget(self, action: "startRecording:", forControlEvents: .TouchUpInside)
            sender.setTitle("Start Recording", forState: .Normal)
            sender.setTitleColor(UIColor.blueColor(), forState: .Normal)
        }else{
                
        }
    }
}

上面的代码我们还需要实现了replaykit框架的一个delegate。RPPreviewViewControllerDelegate
以下是他的两个delegate方法
// 此方式是点击view之后 弹出视频预览页面,可以直接返回 可以保存 也可以分享 通过activityTypes的返回字段可以拿到相应的状态

func previewController(previewController: RPPreviewViewController, didFinishWithActivityTypes activityTypes: Set) {
    print("\(activityTypes)")
        
    if activityTypes.contains("com.apple.UIKit.activity.SaveToCameraRoll")  {
        print("存储视频")
    }else{
        print("取消")
    }
}
// 这是点击视频预览页面顶部两个按钮之后执行的操作
func previewControllerDidFinish(previewController: RPPreviewViewController) {
    previewController.dismissViewControllerAnimated(true, completion: nil)
}

Swift – UIAlertController

iOS 8 之后苹果出了一个UIAlertController,这个使用起来会比原来的UIAlertView 更加灵活一些,同时也可以集成上拉菜单。可以任意添加textfield,并且通过block来更方便的实现内部方法。
下面写一下简单集成,首先创建一个UIAlertController:
[code lang=”Objective-C”]
let alertController = UIAlertController(title: “标题”, message: “这个是UIAlertController的默认样式”, preferredStyle: UIAlertControllerStyle.Alert)
// 添加两个TextField
alertController.addTextFieldWithConfigurationHandler {
(textField: UITextField!) -> Void in
textField.placeholder = “登录”
// 在此可以添加一个textField的监听,对里面输入的内容可以进行分辨
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector(“alertTextFieldDidChange:”), name: UITextFieldTextDidChangeNotification, object: textField)
}
alertController.addTextFieldWithConfigurationHandler {
(textField: UITextField!) -> Void in
textField.placeholder = “密码”
textField.secureTextEntry = true
}
// 取消按钮
let cancelAction = UIAlertAction(title: “取消”, style: UIAlertActionStyle.Cancel, handler: nil)
alertController.addAction(cancelAction)
// 普通按钮(在此可以直接添加按钮点击的响应事件)
let okAction = UIAlertAction(title: “好的”, style: UIAlertActionStyle.Default) {
(action: UIAlertAction!) -> Void in
let login = (alertController.textFields?.first)! as UITextField
let password = (alertController.textFields?.last)! as UITextField
print(“\(login.text)—\(password.text)”)
// 上一个添加的textField监听可以在此移除
NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: nil)
}

alertController.addAction(okAction)
// 警告按钮
let resetAction = UIAlertAction(title: “警告”, style: UIAlertActionStyle.Destructive, handler: nil)
alertController.addAction(resetAction)

presentViewController(alertController, animated: true, completion: nil)
然后需要实现textField的监听方法

func alertTextFieldDidChange(notification: NSNotification){
let alertController = presentedViewController as! UIAlertController?
if (alertController != nil) {
let login = (alertController!.textFields?.first)! as UITextField
let okAction = alertController!.actions.last! as UIAlertAction
// 读取字符串长度(1汉字=3长度)
print("\(login.text?.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))")
// 读取字符串长度(1汉字=1长度)
print("\(login.text?.characters.count)")
}
}
[/code]
接下来写下上拉菜单的集成:
[code lang="Objective-C"]
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .ActionSheet)

let cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.Cancel, handler: nil)
let deleteAction = UIAlertAction(title: "删除", style: UIAlertActionStyle.Destructive, handler: nil)
let archiveAction = UIAlertAction(title: "保存", style: UIAlertActionStyle.Default, handler: nil)
alert.addAction(cancelAction)
alert.addAction(deleteAction)
alert.addAction(archiveAction)

self.presentViewController(alert, animated: true, completion: nil)

// 此代码为iPad上运行时所需要,在iPad上不需要写取消按钮,点击其他区域默认取消
let popover = alert.popoverPresentationController
if (popover != nil){
popover?.sourceView = sender
popover?.sourceRect = sender.bounds
popover?.permittedArrowDirections = UIPopoverArrowDirection.Any
}[/code]

Swift 获取iPhone设备相关信息

获取iPhone机器名称:UIDevice.currentDevice().name
获取设备当前版本:UIDevice.currentDevice().systemVersion
获取设备当前系统名称:UIDevice.currentDevice().systemName
获取设备当前系统名称:
UIDevice.currentDevice().identifierForVendor?.UUIDString
获取设备运营商名称:
import CoreTelephony
CTTelephonyNetworkInfo().subscriberCellularProvider?.carrierName
也可以使用:
CTTelephonyNetworkInfo().currentRadioAccessTechnology
是设备震动:
import AudioToolbox
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
获取设备电池电量:
UIDevice.currentDevice().batteryMonitoringEnabled = true
// 需要注意在iOS8 之前只能精确到0.05 iOS8之后可以精确到0.01
UIDevice.currentDevice().batteryLevel

iOS 3D Touch 这个技能不白学

随着iOS9和6S的到来,3D Touch已经被人们逐渐熟悉和使用,所以本篇主要讲讲这个新技能如何get,以及如何做的更出色。

首先可以先判断该设备是否支持3D touch:
[code lang=”Objective-C”]if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
// UIViewControllerPreviewingDelegate
[self registerForPreviewingWithDelegate:self sourceView:_imageView];
}[/code]
然后实现delegate:
[code lang=”Objective-C”]- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
{
    UIButton *imageView = (UIButton *)[previewingContext sourceView];
    [previewingContext setSourceRect:imageView.bounds];

    POPViewController *p = [[POPViewController alloc] init];
    p.preferredContentSize = CGSizeMake(0, 100);
    p.view.backgroundColor = [UIColor blackColor];
    return p;
}[/code]
[code lang=”Objective-C”]- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit
{
    [self presentViewController:viewControllerToCommit animated:YES completion:nil];
}[/code]
这样可以简单完成一个3D touch Demo,想要实现上拉展示文字可以这样做:
[code lang=”Objective-C”]- (NSArray *)preActions
{
    if (!_preActions) {   
    UIPreviewAction *action0 = [UIPreviewAction actionWithTitle:@”test” style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
    }];

    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@”test1″ style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {

    }];

    UIPreviewActionGroup *actionGroup = [UIPreviewActionGroup actionGroupWithTitle:@”actionGroup” style:UIPreviewActionStyleSelected actions:@[action0, action1]];

    _preActions = @[action0, action1, actionGroup];
    }

    return _preActions;
}
[/code]
[code lang=”Objective-C”]
// 设置控制器在弹窗时候,下面输出的数组- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
{
    return self.preActions;
}[/code]
以上就是粗略的实现了内部3D touch 的功能

WebView只需要添加
[code lang=”Objective-C”]webView.allowsLinkPreview = YES[/code]
即可实现3D touch 的功能
[code lang=”Objective-C”]UITouch *touch = touches.anyObject;[/code]
touch.force这个可以看到用的按压的力度做出相应的判断

来聊聊苹果商店审核的标准吧

说道苹果审核制度,让我想起了光腚总局的审核,但也还好啊,只要不犯大错还是没问题可以上架的。

首先提及一下2015.3 苹果发布的最新审核标准,这个里面大家可以自己看下啊。

其次还包含一些敏感字眼,例如新闻app,频道栏不包含美女,女人等字样;活动web页底部要加本次活动与苹果无关;尽量也不要一个app都是通过web来完成;带有广告的一定在发布的时候注明;

使用QQ授权登录不要跳转下载QQ页面。

还有很多up主可能没遇到的,一下是不喜欢跳链接的人可以直接在下方观看。

前言

感谢您付出宝贵的才华与时间来开发iOS应用程程序。从职业与报酬的角度而言,这对于成千上万的开发员来说一直都是一项值得投入的事业,我们希望帮助您加入这个成功的组织。我们发布了《App Store审核指南》(App Store Review Guidelines),希望通过它帮您避开开发应用程序过程中的一些问题,并帮你在提交应用时加快审核流程。

我们将应用程序(Apps)视为与书籍或歌曲不同的产品,我们并不存储它们。如果您意欲批评宗教,那就去写本书。如果您想要描述性,那就写本书或写首歌,或者可以创建一个医疗程序。这么做可能会比较复杂,但是我们不允许在应用程序商店(App Store)出现某种禁止内容。这会让您认识到我们秉持的更为深远的目的:

我们有很多可供儿童可以下载的应用程序。家长的监护可以很好地保护孩子,但是您需要做您应该做的那一部分。因此,您要了解我们时刻在留心着您的孩子。

App Store中有数百万的应用。如果您的应用程序没有什么有益的用途,不是独一无二的或者不能提供持续性的娱乐功能,那它可能不会被我方接受。

如果您的应用程序看上去像是那种只花了几天功夫简单拼凑出来的产品,或者只是想在我们的商店中抓住朋友的眼球,请提前做好被拒的准备。我们有很多态度严谨的开发者,不希望他们的高品质应用程序充斥在一些业余作品之中。

我们将拒绝任何包含越界内容或行为的应用程序。您可能会问道,具体限制是什么?最高法院的法官曾有言:“它出现时我自然心中有数。”当您越过这一范围时,我们认为您也会有自知之明。

如果您的应用程序被拒,我们设立了一个审查委员会供您上诉。如果您去媒体抨击我们,肯定对您于事无补。

如果您试着作弊(比如在审核流程中作假,窃取用户数据,抄袭其他开发者作品,或者操作应用评分),我们将会移除您的应用程序,并且将您从开发者计划中除名。

这是一个动态文档,新提交的应用程序会导致新的问题产生,并可能随时产生新的规则。或许您的应用程序会触及到这一点。

最后要说明的是,我们非常珍惜这个平台,并且向您的作品表示敬意。我们确实在尝试尽力创建全球最佳平台,以便让您展示才华,同时获得相应的报酬。如果这读上去让您感觉我们的控制欲过强,那是因为我们曾向用户承诺保证,我们将利用我们的产品让他们获得高品质体验。

目录

1.条款与条件

2.功能

3.元数据

4.位置

5.推送通知

6.游戏中心

7.广告

8.商标与商品外观

9.媒体内容

10.用户界面

11.购买与货币

12.抓取与聚合

13.设备损害

14.人身攻击

15.暴力

16.令人反感的内容

17.隐私

18.色情

19.宗教、文化与种族

20.竞赛、赌博、彩票和抽奖

21.慈善与援助

22.法律要件

23.Passbook

24.儿童类别

25.扩展

26.HomeKit

27.HealthKit

28.TestFlight

29.Apple Pay

1. 条款和条件

1.1 为App Store开发程序,开发者必须遵守 Program License Agreement (PLA)、人机交互指南(HIG)以及开发者和苹果签订的任何协议和合同。以下规则和示例旨在帮助开发者的程序能获得App Store的认可,而不是修改或删除任何其他协议中的条款。

2. 功能

2.1 崩溃的程序将会被拒绝。

2.2 存在错误的程序将会被拒绝。

2.3 跟开发者宣传不符的程序将会被拒绝。

2.4 无应用文档或隐藏功能与描述不符的程序将会被拒绝。

2.5 使用非公开API的程序将会被拒绝。

2.6 在指定容器范围外读写数据的程序将会被拒绝。

2.7 以任何方式或形式下载代码的程序将会被拒绝。

2.8 安装或运行其他可执行代码的程序将会被拒绝。

2.9 beta版、demo版、trial版和test版的程序将会被拒绝。

2.10 iPhone程序必须不经修改就能以iPhone分辨率和2倍 iPhone 3GS的分辨率在iPad上运行。

2.11 与App Store已有程序重复的应用可能会被拒绝,特别是数量很多的情况下,比如手电筒应用和爱经应用。

2.12 有用性不显著、不独特的应用或者与网站简单捆绑的应用有可能被拒;不提供任何持久娱乐价值的程序可能会被拒绝。

2.13 主要用于营销或广告的程序将会被拒绝。

2.14 提供欺骗或虚假功能,却有没有明确标示的应用程序将会被拒绝。

2.15 大于100MB(绿色原先是50MB)无法通过蜂窝网络下载的应用(App Store会自动禁止)。

2.16 多任务程序使用后台服务仅限于几种目的:VoIP,音频播放,地理位置,完成任务以及本地提醒等。

2.17 应用程序只允许使用iOS WebKit框架和WebKit Javascript浏览web内容。

2.18 鼓励酗酒或使用违禁药物,或引诱青少年饮酒或吸烟的程序将会被拒绝。

2.19 提供错误的系统诊断或设备数据的应用将会被拒绝。

2.20 向App Store上传大量相似版本程序的开发者将会从iOS开发者计划中除名。

2.21 简单的歌曲或者影片应用要提交到iTunes store,书籍类应用应该提交到iBookstore。

2.22 武断地根据环境(如定位或者运营商)限制用户使用的应用会被拒。

2.23 应用必须遵守iOS数据储存指导方针(iOS Data Storage Guidelines ),否则应用将被拒。

2.24 存放在Newsstand的应用必须遵守开发者项目许可协议(Developer Program License Agreement)的表1、表2以及表3,否则应用将会被拒。

2.25 类似App Store,基于购买或者促销的目的而展示其他应用的应用将会被拒绝,除非是经过特殊审核批准(比如健康管理、航空以及其他无障碍需求等),或者为特殊群体用户提供具有重大意义的附加值的应用。

2.26 只有当app采集是出于特殊审核需求时,app才可以展示和推荐自身以外的其他应用程序,比如健康管理、航空以及无障碍需求等,否则应用程序将会被拒绝。

3. 元数据(名称、描述、评级、排名等)

3.1 应用或者元数据中提到其他任何移动平台将会被拒。

3.2 带有占位符文本的程序将会被拒绝

3.3 描述中有与程序内容和功能不相关的信息的应用将会被拒绝。

3.4 为了不混淆用户,iTunes Connect中的应用名称应该和展示在设备上的应用名称一致。

3.5 不同尺寸的app icon要一致,否则会造成混淆。

3.6 程序图标和截图不符合4+年龄评级的程序将会被拒绝。

3.7 目录与类型不适合于程序内容的程序将会被拒绝。

3.8 开发者有责任为其程序指定适合的评级。不相称的评级可能会由苹果公司修改。

3.9 开发者有责任为其程序指定恰当的关键字。不恰当的关键词可能会被苹果公司修改/删除。

3.10 有以下行为的开发者将会被苹果从iOS开发者计划中除名:试图操纵或者欺骗用户评级,伪造或者付费评级,以及其他不相称的行为。

3.11 在安装下载之前推荐用户重启iOS设备的应用将会被拒。

3.12 在提交审核过程中,应用程序应包含能正常运行的URL,比如支持URL和隐私政策URL。

3.13 如果应用程序的截图和营销文本没有清晰地确定需要额外单独购买(比如使用IAP)的内容或者项目,那么应用程序将会被拒绝。

3.14 App预览可以仅使用从应用程序捕获的视频屏幕、旁白、文本以及design overlays,否则应用程序将会被拒绝。(10.11更新)

3.15 添加App预览的应用程序,未经许可展示真人个人信息将会被拒绝。(10.11更新)

3.16 App预览可能仅包括在所有选定地区内经过授权许可用于此目的的音乐。(10.11更新)

3.17 App预览包含未经许可的通过app播放的内容(比如iTunes playlist和YouTube流媒体)的应用将会被拒绝。(10.11更新)

4. 位置

4.1 在收集、传输或使用位置数据之前未通知并获得用户同意的程序将会被拒绝。

4.2 使用基于位置的API来自动控制车辆、飞机或其他设备的应用程序将会被拒绝。

4.3 使用基于位置的API用于调度、车队管理或应急服务的程序将会被拒绝。

4.4 当与应用功能或服务密切相关时可以使用位置数据,或者用于经过授权的广告。(10.11更新)

5. 推送通知

5.1 不使用苹果推送通知 (APN)应用接口提供推送通知的程序将会被拒绝。

5.2 未从苹果获得Push Application ID便擅自使用APN服务的程序将会被拒绝。

5.3 在首次推送消息或者要求推送通知运行之前未获得用户许可的应用将会被拒绝。

5.4 使用推送通知发送敏感个人信息或机密信息的程序将会被拒绝。

5.5 使用推送通知发送非请求消息或用于钓鱼或群发垃圾邮件用途的程序将会被拒绝。

5.6 应用程序不可使用推送通知发送广告、促销或任何类型的直销信息。

5.7 应用程序不能向使用推送通知服务的用户收取费用。

5.8 使用推送通知会过多利用APN服务的网络流量或带宽或给设备带来过度负担的程序将会被拒绝。

5.9 如果应用程序传送病毒、文件、计算机代码或程序,并且对APN服务的正常运行造成损害或中断,那么该程序将会被拒绝。

6. 游戏中心

6.1 向终端用户或任意第三方显示玩家ID的程序将会被拒绝。

6.2 将玩家ID用于任何未经游戏中心条款批准用途的程序将会被拒绝。

6.3 试图进行反向搜索、跟踪、关联、挖掘、获得或利用玩家ID、别名或通过游戏中心获得其他信息的开发者将会iOS开发者计划除名。

6.4 游戏中心信息(例如排行榜分数)只能通过游戏中心用于应用中。

6.5 利用游戏中心服务发送非请求信息或用于钓鱼或群发垃圾邮件的程序将会被拒绝。

6.6 使用游戏中心过多占用网络流量或带宽的程序将会被拒绝。

6.7 如果程序能够传送病毒、文件、计算机代码或程序,并且对游戏中心服务的正常运行造成损害或中断,该程序将会被拒绝。

7. 广告

7.1 人工刷广告浏览量或者广告点击率的应用程序将会被拒绝。

7.2 包含空iAd广告的应用程序将会被拒绝。

7.3 主要设计目的在于显示广告的应用程序将会被拒绝。

8. 商标与商品外观

8.1 应用程序必须遵守“Guidelines for Using Apple Trademarks and Copyrights”和“Apple Trademark List”中说明的所有条款与条件。

8.2 任何误导和暗示苹果公司是该应用程序来源或提供商,或者苹果公司以任何形式表示认可其质量或功能的应用程序将会被拒绝。

8.3 与目前已有苹果产品或者广告主题外观相似或混淆的应用程序将会被拒绝。

8.4 在应用程序名称中将苹果产品名拼错的应用程序(例如,GPS for Iphone,iTunz)将会被拒绝。

8.5 使用受保护的第三方材料(商标、版权、商业机密、其他私有内容)在申请时需要提供一份文本形式的版权确认。

9. 媒体内容

9.1 不使用媒体播放器框架(MediaPlayer Framework)获取音乐库中媒体内容的应用程序将会被拒绝。

9.2 用户界面模仿任何iPod界面的应用程序将会被拒绝。

9.3 通过蜂窝网络传输的音频流内容每5分钟不得超过5MB。

9.4 通过蜂窝网络传输超过10分钟的视频流内容需要使用HTTP Live Streaming,并包含一个基准线为64kbps的音频HTTP Live Streaming。

10. 用户界面

10.1 应用程序必须遵守苹果的《iOS Human Interface Guidelines》中所有的条款和条件。

10.2 外观与与iPhone的自带应用(比如App Store、iTunes Store和iBookstore)相似的应用将会被拒绝。

10.3 未能按苹果《iOS Human Interface Guidelines》描述正确使用系统提供的项目(比如按钮、图标)的应用将会被拒绝。

10.4 创建多桌面/主屏幕环境或者模拟multi-App插件体验的应用程序将会被拒绝。

10.5 修改音量大小和铃声/静音开关等标准开关功能的应用程序将会被拒绝。

10.6 苹果和我们的客户高度推崇简单、精致、富有创造性以及经过精心设计的界面。虽然需要付出更多,但却非常值得。苹果设立了很高的门槛。如果你的用户界面太过复杂或者水准不高,可能会被拒绝。

11. 购买与货币流通

11.1 使用App Store以外的渠道解锁或开启附加属性和功能的应用程序将会被拒绝。

11.2 使用应用内支付系统(IAP)以外的系统购买内容、功能或服务的应用软件将会被拒绝。

11.3 使用IAP购买实物商品和并非用于该软件的服务的应用软件将会被拒绝。

11.4 应用程序使用IAP购买积分(Credit)或者其他的货币必须在本应用中消费。

11.5 使用IAP购买已过期积分(Credit)或者其他货币的应用软件将会被拒绝。

11.6 使用IAP订阅的内容至少要持续7天,而且允许在用户的其他iOS设备间共享。

11.7 应用程序使用IAP购买项目必须分派到正确的购买类型中。

11.8 使用IAP购买iOS内置功能(如照相机,陀螺仪)的应用程序将会被拒绝。

11.9 含有超过限定时间的内容或服务的应用程序将会被拒绝,除了特殊批准的内容(比如films、电视节目音乐以及书籍)。

11.10 保险类应用程序必须免费,遵守发布地区的法律,并且不能使用IAP。

11.11 一般而言,你的应用程序越贵,我们的评审越彻底。

11.12 提供订阅功能的应用必须使用IAP,苹果将会按照 Developer Program License Agreement 中的约定与开发者按30/70比例分成。

11.13 在应用内使用跳转至外部购买或订阅链接的应用将会被拒,比如“buy”按钮跳转至一个购买电子书的web页面。

11.14 只要应用内没有跳转至外部购买、订阅的按钮或链接,苹果允许这些应用读取或展示经批准的、在应用外购买或订阅内容(特别是杂志、报纸、书籍、音频、音乐、视频以及云存储内容)。苹果只能通过应用程序内的购买获得一部分收益。

11.15 应用程序可以只使用自动更新订阅期刊(报纸、杂志)、商业应用程序(企业类、效率类、专业创意类以及云存储类)和媒体应用程序(视频、音频、声音),否则应用程序将被拒绝。

11.16 当与特定的经过审核的实体产品(比如玩具)结合使用时,应用程序可以使用获得批准的附件功能,只要附加功能完全依赖于该硬件产品(比如一款用于控制望远镜的应用程序)或者也可以在不使用实物产品的情况下使用应用程序,比如作为成功的奖励或者使用IAP。

11.17 如果应用功能遵照各州和联邦法律,那么应用可以用来促进被认可的虚拟货币的流通。

12. 抓取和聚合

12.1 从苹果网站(例如apple.com、iTunes Store、App Store、iTunes Connect以及Apple Developer Programs等)抓取任何信息或者使用苹果网站内容和服务进行排名的应用程序将会被拒绝。

12.2 应用软件可以使用获得批准的苹果RSS feeds,例如iTunes Store RSS feeds。

12.3 只是简单的网页剪切、内容整合或者收集链接的应用程序可能会被拒绝。

13. 损害设备

13.1 怂恿用户以可能造成损害的方式使用苹果设备的应用软件将会被拒绝。

13.2 快速耗光设备电量或产生过多热量的应用软件将会被拒绝。

13.3 能导致用户人身伤害的app将会被拒绝。

14. 人身攻击

14.1 涉及诽谤、人身攻击性质以及内容狭隘卑鄙的应用软件或者打击特定个人或组织的应用软件将会被拒绝。

14.2 职业政治讽刺家和幽默作家不受这一条款约束。

14.3 展示用户创作内容(UGC)的应用程序必须提供一个过滤不良资讯的方法,一个用户可以标记具有侵犯性内容的机制以及可以阻止辱骂用户的能力。(10.11更新)

15. 暴力

15.1 应用程序中出现人或动物被杀、致残以及枪击、刺伤、拷打等受伤情形的真实画面将会被拒绝。

15.2 出现描绘暴力或虐待儿童等内容的应用程序将会被拒绝。

15.3 游戏中出现的“敌人”不可指向一个特定种族、文化、一个真实存在的政府、企业或者其他任何现实中的实体。

15.4 对武器进行真实描述以怂恿非法使用或滥用这些武器的应用程序将会被拒绝。

15.5包含俄罗斯轮盘赌博内容的游戏将会被拒。

16.令人反感的内容

16.1 应用程序中出现过于令人反感或者低俗的内容将会被拒绝。

16.2 在设计上激怒用户或令人感到厌恶的应用程序将会被拒绝。

17.隐私

17.1 在未经用户事先许可,或未告知用户如何使用信息,在何处使用信息的情况下,应用程序不能传输用户数据。

17.2 要求用户提供电子邮箱地址和出生日期等私人信息才可使用其功能的应用程序将会被拒绝。

17.3 仅出于遵守适用的儿童隐私法规的目的,应用程序可以要求用户的出生日期(或者使用其他age-gating机制),但是必须包括一些有用的功能或者娱乐价值,不管用户年龄大小。

17.4 应用程序收集、传输以及分享未成年用户个人信息(比如名字、地址、邮件、位置、照片、视频、绘画、聊天以及其他个人数据,或者与以上所述相关的永久性标示符)必须遵守应用儿童隐私法规,并且必须包含隐私条款。

17.5 包含账号注册或者访问用户现有账号的应用程序必须包含隐私策略,否则将会被拒绝。

18. 色情

18.1 含有色情素材,也就是《韦氏词典》中定义的“旨在激发情欲,对性器官或性行为的明确描述或展示,而无关美学或情绪感受”的程序将会被拒绝。

18.2 用户频繁提供生成色情内容的应用程序(比如以前的Chat Roulette程序)将会被拒绝。

19.宗教,文化与种族

19.1 涉及宗教、文化或种族群体的引用或评论包含诽谤性、攻击性或狭隘内容,或会使特定群体遭受伤害或暴力的应用程序将会被拒绝。

19.2 程序可以包含或引用宗教经文,程序所提供的引用或翻译必须准确且不会引起误导。评论应该有教育意义,可以令人开阔眼界,而不应有煽动性。

20. 竞赛、赌博、彩票以及抽奖

20.1 赌博和竞赛必须由应用程序的开发者或者app所属公司发起。

20.2 应用程序必须展示赌博和竞赛的正式规则,并声明苹果不是发起者,也没有以任何方式参与活动。

20.3 开发者运营一款具有抽奖性质的应用必须经过法律允许,并且抽奖应用必须具备以下特征:报酬、机会以及奖品。

20.4 允许用户在应用中直接购买彩票或彩券的应用将会被拒。

20.5 提供真钱游戏(比如体育博彩、扑克牌、赌场游戏以及赛马)的应用程序必须有应用使用区当地必要的许可和允许,必须限制在这些区域,必须可以从App Store免费下载。

20.6 使用IAP购买信誉或者货币,且结合真钱游戏的应用将会被拒绝。

21.慈善与援助

21.1 包含可以向已认证的慈善组织捐赠功能的应用程序必须是免费的。

21.2 捐赠款项的募集必须通过Safari浏览器访问web页面或是手机短消息完成。

22. 法律要件

22.1 应用程序必须遵守所有发布地区当地法律,开发者有义务了解并遵守所有当地法律。

22.2 包含虚假,欺诈或误导性陈述的程序将会被拒绝。

22.3 任何招徕、促进或鼓励犯罪或明显鲁莽行为的程序将会被拒绝。

22.4 支持非法文件共享的程序将会被拒绝。

22.5 被设计用以非法赌博工具的应用程序(包括点算牌)将会被拒绝。

22.6 具有匿名或恶作剧拨打电话或发送类似短信/彩信功能的程序将会被拒绝。

22.7 任何开发暗中收集用户密码或用户私人数据程序的开发者将会从iOS开发者计划中除名。

22.8 包含非法律执行部分发布的DUI检查点信息,或者怂恿/协助酒后驾车的应用将会被拒绝。

22.9 任何计算药用剂量的应用必须提交药品制造商或者认可机构(比如医院、保险公司以及高校)。

22.10.在未授权的情况下使用iTunes音乐预览的应用程序将会被拒绝。(新增)

23. Passbook

23.1 Passbook Passes可被用来支付或者接收支付,传递商业信息或者提供验证(比如电影票、飞机票、优惠券以及其他),而把Passbook Passes用于其他用途的应用程序可能会遭到拒绝,并且会被撤销Passbook证书。

23.2 Passes必须包含有效的pass发行人有效的联系资料,否则app将会被拒绝,并且Passbook证书也会被取消。

23.3 Passes必须经过实体签名,并基于其名字、商标或者品牌进行分发,否则应用程序将会被拒绝,而Passbook证书也可能会被撤销。

24.儿童类别

24.1 主要供儿童使用的应用程序必须包含隐私政策,必须适用于应用程序的儿童隐私法。

24.2 主要供儿童使用的应用程序不允许包括行为广告(比如基于用户app内部活动的广告),任何在应用程序中展示的上下文广告必须适合儿童。

24.3 主要供儿童使用的应用程序必须得到家长许可或使用parental gate才能链接至应用程序外部或进行交易。

24.4 儿童类别中的应用程序必须标明“5岁以下,6-8岁或者9-11岁”。

25.扩展

25.1 包含扩展的应用程序必须遵照 App Extension Programming Guide (中文版,英文版)要求。

25.2 包含扩展的应用程序必须提供某些功能(辅助屏幕,附加设置)否则将会被拒绝。

25.3 如果扩展的视图中包含营销推广、广告或者IAP内容,那么包含该扩展的应用将会被拒绝。

25.4 键盘扩展必须提供一个切换至下个键盘的方法。

25.5 键盘扩展必须具有离线访问功能,否则将会被拒绝。

25.6 键盘扩展必须提供和 App Extension Programming Guide 描述一致的数字和十进键盘类型,否则将会被拒绝。

25.7 提供键盘扩展的应用必须拥有基本的功能分类和隐私政策,否则将会被拒绝。

25.8 提供键盘扩展的应用程序只允许收集用户活动以增强键盘扩展在iOS设备上的功能,否则将会被拒绝。

26.HomeKit

26.1使用HomeKit框架的应用程序必须有提供家庭自动化服务的主要目的。

26.2 使用HomeKit框架的应用程序必须在营销文本中说明用途,同时必须提供隐私政策,否则将会被拒绝。

26.3应用程序不允许将从HomeKit API收集的数据用于广告宣传或者其他基于使用的数据挖掘。

26.4 出于其他目的使用从HomeKit API收集的数据,而不是用于提高用户体验或者家庭自动化功能中硬件/软件性能,这类应用将会被拒绝。

27.HealthKit

27.1 使用HealthKit框架的应用程序必须遵守其所在区域的适用法律,以及iOS Developer Program License Agreement中的3.3.28和3.39条款。

27.2将虚假或者错误的数据写入HealthKit的应用程序将会被拒绝。

27.3 使用HealthKit框架iCloud中储存用户健康信息的应用程序将会被拒绝。

27.4 应用程序不允许将通过HealthKit API收集的用户数据用作广告宣传或者基于使用的数据挖掘目的,除了改善健康、医疗、健康管理以及医学研究目的。

27.5 未经用户许可与第三方分享通过HealthKit API获得的用户数据的应用程序将会被拒绝。

27.6 使用HealthKit框架的应用程序必须在营销文本中说明集成了Health app,同时必须在app用户界面清楚阐释HealthKit功能。

27.7使用HealthKit框架的应用程序必须提供隐私政策,否则将会被拒绝。

27.8 提供诊断、治疗建议或者控制硬件以诊断或者治疗疾病的应用,若没有根据要求提供书面的监管审批,将会被拒绝。

28.TestFlight

28.1应用程序仅能使用TestFlight对以公开发布为目的的应用进行beta版测试,且必须遵守完整的App Review Guidelines。

28.2 当版本中包含的内容或功能有重大变化时,使用TestFlight的应用程序必须提交审核。

28.3 使用TestFlight的应用程序不允许分发给测试者,以作为任何形式的补偿。

29. Apple Pay

29.1 使用Apple Pay的应用程序必须在出售任何商品或者服务之前为用户提供所有材料的购买信息,否则将会被拒绝。

29.2 使用Apple Pay的应用程序必须正确使用 Apple Pay Human Interface Guidelines 中的Apple Pay标识和用户界面元素,否则将会被拒绝。

29.3 使用Apple Pay的应用程序不能提供触犯任何领域范围法律的用于交付的商品或者服务,也不能用作任何非法目的。

29.4 使用Apple Pay的应用程序必须提供隐私政策,否则将会被拒绝。

29.5 只有为了促进或提高商品和服务的交付,或者依照法律要求,使用Apple Pay的应用程序才能与第三方分享通过Apple Pay获得的数据。

动态文档

这份文档展现了我们在竭尽所能向您分享我们对提交到App Store的程序的审查方式,我们希望您在开发和提交程序时,这份指南能对您有所帮助。这是一份动态文档,随着新程序和新情况的发生会有所变化。我们会定期更新,以反映这些变化。

感谢您参与到iOS的开发中来。虽然此文档是一份“不该做事宜”的列表,但也请将那份短得多的“必做事宜”列表牢记在心。最重要的是,与我们一道 共同努力让用户感到惊奇和欣喜。用创新方式向他们展示世界,让他们用前所未有的方式与之交流。根据我们的经验,无论是在功能和用户界面上,用户确实会对完 善的程序有所反应。更进一步,给他们期望之外的东西,带他们去从未去过的地方。我们愿意提供帮助。

另外附加两个链接:

10个大坑,当你产品上架AppStore会遇到(上) – 十万产品经理 – 知乎专栏
10个大坑,当你产品上架AppStore会遇到(下) – 十万产品经理 – 知乎专栏

iOS 和H5打交道的那些事 JavaScript & iOS

前言:

现在面试都很流行问的一个问题:H5 和iOS 交互做过吗?

做过?说说具体如何实现。没做过?不好意思我们再考虑一下。

今天就和大家一起分享,探讨这个流行问题的答案,首先我们要有一个自己的H5页面,还要有一个xcode,以及一个大脑。

交互方法一:stringByEvaluatingJavaScriptFromString

这个方法可以传递数据给H5,也可以调用H5的function,拿到返回值到app中,这也需要H5和app做一个相互约束的方法名称才能完成此操作。
[code lang=”Objective-C”]UIWebViewDelegate:- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType[/code]
这个方式可以在点击H5按钮等点击事件时做相应的拦截,截取需要的信息

注:这个方法是放在主线程进行的,所以有时会出现卡顿现象影响用户体验

交互方法二:JavaScriptCore

JavaScriptCore是iOS7之后苹果推出的JS交互方法,交互也相对简单了很多。

首先包含文件:

#import <JavaScriptCore/JavaScriptCore.h>

我们可以在webViewDidFinishLoad 里面获取JS的上下文
[code lang=”Objective-C”]JSContext *context = [webView valueForKeyPath:@”documentView.webView.mainFrame.javaScriptContext”];[/code]
在H5调用app的时:
[code lang=”Objective-C”]// xxxx 是H5中的方法名称,可以通过此方法调用app端做相应操作,可以在JSValue里面获取相应的值做处理
context[@”xxxx”] = ^() {
NSArray *args = [JSContext currentArguments];
for (JSValue *jsVal in args) {
}
}[/code]
app想调用H5则是:
[code lang=”Objective-C”]// xxxx是H5里面的方法名称 yyyyyyy 里面是H5方法里面相对于的一些参数
NSString *textJS = @”xxxx(‘yyyyyyy’)”;
[context evaluateScript:textJS];[/code]
以上就是对H5 和 app 相互交互的理解了,可以多加练习,就会逐渐理解了。
借鉴的文章地址:iOS下JS与原生OC互相调用(总结)