如何在孩子的部分实现iOS应用程序的父门

时间:2013-10-02 03:54:48

标签: ios parental-control

我正在更新我的应用程序,因为App Store拒绝二进制文件,因为我的应用程序包含指向“信用”页面中网站的链接。我需要实现一个父门,以限制对“信用”视图控制器的访问。

我找到了一个检查应用内购买权限的代码。但我想我不能为此目的使用同样的东西?

如何在打开视图控制器之前检查父级权限?

7 个答案:

答案 0 :(得分:3)

My Application was rejected for same reason . I added Parental gateway on App upgrade but I had advertisement in my app that hence it was rejected again as tapping advertisement leaves application and open itune stores. I am not sure if anyone can ask parental question after tapping advertisement and before opening external link.

I see two solution 1. Remove advertisement from app 2. Deselect Made for Kids

Does it mean that we can not have advertisement for apps made for Kids?

答案 1 :(得分:2)

我发布了一个开源的Parental Gate SDK,该SDK已经在Apple的新24.3规则中成功通过审核的应用程序中使用,该规则需要在应用程序购买中使用“父门”以及将用户体验带到网页。您可以在此处阅读有关SDK的更多信息并获取代码:

MKParentalGate Open Source SDK

答案 2 :(得分:1)

我最近刚刚和Apple谈过此事。

首先,他们将把这个留给开发人员实施,而不必告诉我们他们会接受什么。但是,我确实设法从Apple获得了它真正依赖于你所针对的年龄组。如果你要去年龄较大的年龄组,父母门必须更难克服。

一个简单的弹出窗口告诉用户只有在那个点之后它才会成人。必须有其他东西阻止用户。多触摸滑动,数学问题和历史问题被认为是可以接受的。

我担心的是,我知道很多父母不能做我在一些(45 + 62等)中使用的简单算术运算。历史问题很难,因为我国的历史与你的不同(班诺克本的战斗是什么时候?)。我所看到的一个方法就是提供多种选择答案,但有三个选项就有33%的猜测机会就足够了!多点触摸滑动太容易了。

理想情况下,苹果应该将其作为需要密码的iOS的一部分。至少它会标准化父母门。

我根据第四行选项和另一个问题选择了四个选项中的一个来放入父母门。我打算在这里做的是让测试对于父母来说足够容易,但同时不太可能随机猜测会解决这个难题。四个选项是25%的正确率,第二个问题减少到6%。我认为这对我的目标要求更年轻。

**接受了我父母之门的版本。从第一个视图控制器我打电话给父母门。如果失败,它将解散并创建一个UIAlertView,说明它失败了。如果它通过,那么它也将解雇并在完成时发送成功通知。调用视图控制器接收通知,然后执行它不会做父母门时所做的任何事情!

答案 3 :(得分:1)

鉴于此处似乎仍存在很多不确定因素,我认为我会分享自己的经历。

因为我为年幼的孩子(六岁或类似的东西)制作应用程序,我可以假设父母门不需要太困难。目前我实现了一个简单的UIAlertView,询问数学问题。由于在其他一个答案中做出的评论,我实际上正在使这个问题变得更简单。

我正在做的是在10到30之间取两个随机数并请求用户添加并输入答案。不幸的是因为我现在正在UIAlertView中执行此操作并且我需要一个编辑字段,这将iOS的使用范围提高到5.0。查看我的应用程序的Flurry数据,在过去的一个月中,iOS 5下的任何内容几乎没有注册(不到总数的1%),所以我不太关心它。

我仍然在考虑是否我不能让这对成年人更简单,但不一定是因为我们学到的数学知识对孩子来说。例如,确保要添加的任何数字均匀,可能会使许多人更容易。使用五个中的多个可以使它更容易,而我认为孩子们根本没有学过这些技巧,所以对他们来说没有太大的区别。

我在App Store中有三个不同的应用程序使用相同的方法,他们都被接受了,即使他们得到了不同的人的评论(我可以告诉他们在其他方面的决定有多么愚蠢)所以我假设这种方法是受到制裁的。我还没有尝试过一种方法来判断用户是否觉得这很烦人,或者大多数人是否可以毫不费力地处理这个问题。

答案 4 :(得分:1)

您可能想尝试这个cocoapod库: https://cocoapods.org/pods/HYParentalGate

答案 5 :(得分:0)

我为此用户使用swiftUI创建了一个。

它会生成3个随机数字,然后要求您按此顺序按数字按钮,如果正确,它将以不透明的方式隐藏门,因此我在需要门加载的屏幕上使用它,因此当门被隐藏时,显示下面的另一个视图。 如果所按的数字不正确,则会关闭门,并将视图退回到原始视图。

Parent Gate

import SwiftUI

struct GateScreen: View {
@Environment(\.presentationMode) var presentationMode
@State var tInput1 = "1"
@State var tInput2 = "2"
@State var tInput3 = "3"
@State var nP = ""
@State var npP = ""
@State var pressedN  = ""
@State var randN = 0
@State var showingAbout = false
@State var hiddenOpp = 1.0


var body: some View {
    ZStack {
        Color(.white)
    VStack {
        Capsule()
         .fill(Color.gray)
       .frame(width: 80, height: 5)
            .padding(.vertical)
        Spacer()
        Text("""
            This area is for parents only.
            Please press the numbers shown, in order.
            """)
            .padding()
            .font(.system(size: 20))
            .multilineTextAlignment(.center)
            .frame(width: 400)
        Spacer()
        HStack {
            Text(tInput1)
                .font(.system(size: 30))
                .frame(width: 40, height: 40, alignment: .center)
                .overlay(
                        RoundedRectangle(cornerRadius: 16)
                            .stroke(Color.black, lineWidth: 2)
                    )
                .multilineTextAlignment(.center)
                
            Text(tInput2)
                .font(.system(size: 30))
                .frame(width: 40, height: 40, alignment: .center)
                .overlay(
                        RoundedRectangle(cornerRadius: 16)
                            .stroke(Color.black, lineWidth: 2)
                    )
                .multilineTextAlignment(.center)
            
            Text(tInput3)
                .font(.system(size: 30))
                .frame(width: 40, height: 40, alignment: .center)
                .overlay(
                        RoundedRectangle(cornerRadius: 16)
                            .stroke(Color.black, lineWidth: 2)
                    )
                .multilineTextAlignment(.center)
        }
        .padding()
        Spacer()
            HStack {
                Group {

                    Button(action: {
                       pressedN = "0"
                        numbersPressed()
                    }) {
                        Text("0")
                            .font(.system(size: 20))
                                            .fontWeight(.heavy)
                                            .foregroundColor(Color.blue)
                                            .multilineTextAlignment(.center)
                                            .padding(20.0)
                                            .overlay(
                                                    RoundedRectangle(cornerRadius: 16)
                                                        .stroke(Color.blue, lineWidth: 4)
                                                )
                            
                    }
                    Button(action: {
                        pressedN = "1"
                        numbersPressed()
                    }) {
        Text("1")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
            }
         
                    Button(action: {
                        pressedN = "2"
                        numbersPressed()
                    }) {
        Text("2")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                    }
                    Button(action: {
                        pressedN = "3"
                        numbersPressed()
                    }) {
        Text("3")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                    }
                    Button(action: {
                        pressedN = "4"
                        numbersPressed()
                    }) {
        Text("4")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                    }
            }
        }
        HStack {
            Group {
                Button(action: {
                    pressedN = "5"
                    numbersPressed()
                }) {
        Text("5")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                }
                Button(action: {
                    pressedN = "6"
                    numbersPressed()
                }) {
        Text("6")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                }
                Button(action: {
                    pressedN = "7"
                    numbersPressed()
                }) {
        Text("7")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                }
                Button(action: {
                    pressedN = "8"
                    numbersPressed()
                }) {
        Text("8")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                }
                Button(action: {
                    pressedN = "9"
                    numbersPressed()
                }) {
        Text("9")
            .font(.system(size: 20))
            .fontWeight(.heavy)
            .foregroundColor(Color.blue)
            .multilineTextAlignment(.center)
            .padding(20.0)
            .overlay(
                    RoundedRectangle(cornerRadius: 16)
                        .stroke(Color.blue, lineWidth: 4)
                )
                }
                }
            }
        Spacer()
        }
    }
    .opacity(hiddenOpp)
    .onAppear() {
       setNums()
        
    }
}

func setNums() {
    for _ in 0..<3 {
    randN = Int.random(in: 0..<10)
        npP = npP + "\(randN)"
    print("Tony numbers are \(npP)")
}
    let char1 = npP[npP.index(npP.startIndex, offsetBy: 0)]
        tInput1 = "\(char1)"
    
   let char2 = npP[npP.index(npP.startIndex, offsetBy: 1)]
        tInput2 = "\(char2)"
    
    let char3 = npP[npP.index(npP.startIndex, offsetBy: 2)]
        tInput3 = "\(char3)"
}

func numbersPressed(){
    if nP == "" {
        nP = pressedN
        print("Tony numbers are \(nP)")
    }else {
        if nP.count == 1 {
        nP = nP + pressedN
            print("Tony numbers are \(nP)")
    }else {
        nP = nP + pressedN
        print("Tony numbers are \(nP)")
        if nP == "\(npP)" {
            npP = ""
            nP = ""
            print("Tony Corect numbers")
                hiddenOpp = 0.0
        }else {
            self.presentationMode.wrappedValue.dismiss()
           print("Tony Incorect numbers")
            npP = ""
            nP = ""
            setNums()
        }
    }
}
}


}

答案 6 :(得分:0)

这是我今天做的。我还没有得到苹果的回应。已通过应用审核

enter image description here

import SwiftUI

struct Triangle: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()

        path.move(to: CGPoint(x: rect.midX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.midX, y: rect.minY))

        return path
    }
}

struct ParentalGateView: View {

    // MARK: - Properties
    var onClose: (() -> Void)?
    var onCancel: (() -> Void)?
    @State private var circleTapped: Bool = false

    // MARK: - UI Layout
    var body: some View {
        VStack(alignment: .center, spacing: 60) {
            HStack {
                Image(systemName: "arrow.left")
                    .resizable()
                    .frame(width: 40, height: 33)
                    .foregroundColor(.red)
                    .onTapGesture {
                        HapticEngine.select.selectionChanged()
                        onCancel?()
                    }
                Spacer()
            }.padding([.leading, .top], 24)

            Text("Ask your parents")
                .font(.largeTitle)
                .fontWeight(.black)
                .foregroundColor(.blue)

            Spacer()
            HStack(spacing: 130) {
                Button("") {}
                .background(Triangle()
                                .foregroundColor(.green)
                                .frame(width: 100, height: 100)
                                .onTapGesture { !circleTapped ? onCancel?() : print("") }
                                .onLongPressGesture { circleTapped ? onClose?() : onCancel?() })

                Button("") {}
                .background(Rectangle()
                                .foregroundColor(.blue)
                                .frame(width: 100, height: 100))
                                .onTapGesture { onCancel?() }

                Button("") {}
                .background(Circle()
                                .foregroundColor(circleTapped ? .green : .yellow)
                                .frame(width: 100, height: 100)
                                .animation(.easeInOut)
                                .onTapGesture(count: 4) { circleTapped = true })
            }.padding()

            Text("Tap inside the circle until the circle turns green, then hold triangle.")
                .multilineTextAlignment(.center)
                .font(.headline)
                .padding([.leading, .trailing], 16)
                .foregroundColor(.orange)
            Spacer()
        }
    }
}

struct ParentalGateView_Previews: PreviewProvider {
    static var previews: some View {
        ParentalGateView()
            .preferredColorScheme(.dark)
    }
}