Im getting an error using timed walk test in research kit - ios

Im using timed walk from researchkit test in an app that uses carekit as well. However, I have no idea why I am getting this error. Any help would be greatly appreciated. This is what I have so far. (error states Use of unresolved identifier)
import ResearchKit
public var timedWalk: ORKOrderedTask
{return ORKOrderedTask.timedWalk(withIdentifier: "Timed Walk",intendedUseDescription: "Assessment measures balance", distanceInMeters: 3, timeLimit: 13, includeAssistiveDeviceForm: true, options: .excludeConclusion)
//Create a question.
let title = "Estimate your fall Risk"
let text = "This assessment measure how fast you walk to estimate your fall risk. Start from a sitting position stand walk 10 feet turn around and walk back to sitting position"
***let questionStep = ORKQuestionStep(identifier: "Timed Get up and Go", title: title, text: text, answer: answerFormat)***
questionStep.isOptional = false
//Create an ordered task with a single question
return ORKOrderedTask(identifier: "Timed Walk", steps: [questionStep])

Here's a syntactically correct version of the above code:
public var timedWalk: ORKOrderedTask {
return ORKOrderedTask.timedWalk(withIdentifier: "Timed Walk",
intendedUseDescription:" Assessment measure, the, balance",
distanceInMeters: 3, timeLimit: 13, options: .excludeConclusion)
}

Related

Apple pay sheet not showing up for Apple app reviewer

My app keeps getting rejected by the App Review team due to the fact that the Apple Pay button in my app is unresponsive on their device when they tap it. The Apple Pay sheet shows up perfectly fine on my device but never completes the payment (error says my debit card number is invalid, my card works perfectly fine everywhere else, not sure how to fix this, but not the main issue here).
I am not worried about paying with Apple Pay on my app simply because I will not be the one using my app but I do want to ensure it works for everybody else since Apple is bringing it up as a reoccurring issue.
Here is my function for presenting the Apple Pay sheet:
{
guard let cost = actualCostOfEvent.text else { return }
guard let name = nameOfEvent else { return }
let text = cost
let textWithout$ = text.replacingOccurrences(of: "$", with: "")
guard let finalCost = Double(textWithout$) else { return }
let fee = finalCost / Double(12.0)
let roundedFee = floor(fee * 100) / 100.0
let total = finalCost + roundedFee
let paymentRequest = StripeAPI.paymentRequest(withMerchantIdentifier: "merchant.xxxxx.xxxxx.xxxxx",
country: "CA",
currency: "CAD")
paymentRequest.supportedNetworks = [.visa, .masterCard, .interac, .amex, .discover]
paymentRequest.paymentSummaryItems = [
PKPaymentSummaryItem(label: name , amount: NSDecimalNumber(value: finalCost)),
PKPaymentSummaryItem(label: "Service Fee", amount: NSDecimalNumber(value: roundedFee)),
PKPaymentSummaryItem(label: "XXXXXX", amount: NSDecimalNumber(value: total))
]
guard let applePayController = STPApplePayContext(paymentRequest: paymentRequest, delegate: self) else { return }
if StripeAPI.canSubmitPaymentRequest(paymentRequest) {
applePayController.presentApplePay {
self.startApplePayCheckout()
}
}
}
I can't seem to figure out why the Apple Pay sheet doesn't show up for the App reviewer, any suggestions or things needed to be changed? If not, I will just have to submit an appeal.
I have reproduced your code, and it works perfectly fine; the ApplePay sheet is displayed for me. You may want to confirm with Apple what iOS version they are testing and submit an appeal.
A few notes just in case:
You don’t need to check if StripeAPI.canSubmitPaymentRequest(paymentRequest). When you initialized STPApplePayContext it automatically did the check for you: https://github.com/stripe/stripe-ios/blob/master/Stripe/STPApplePayContext.swift#L87
If you are using a test key, you can complete the payment as long as your real card information is correct. You won’t be charged while using a test key.

How to detect text (string) language in iOS?

For instance, given the following strings:
let textEN = "The quick brown fox jumps over the lazy dog"
let textES = "El zorro marrón rápido salta sobre el perro perezoso"
let textAR = "الثعلب البني السريع يقفز فوق الكلب الكسول"
let textDE = "Der schnelle braune Fuchs springt über den faulen Hund"
I want to detect the used language in each of them.
Let's assume the signature for the implemented function is:
func detectedLanguage<T: StringProtocol>(_ forString: T) -> String?
returns an Optional string in case of no detected language.
thus the appropriate result would be:
let englishDetectedLanguage = detectedLanguage(textEN) // => English
let spanishDetectedLanguage = detectedLanguage(textES) // => Spanish
let arabicDetectedLanguage = detectedLanguage(textAR) // => Arabic
let germanDetectedLanguage = detectedLanguage(textDE) // => German
Is there an easy approach to achieve it?
Latest versions (iOS 12+)
Briefly:
You could achieve it by using NLLanguageRecognizer, as:
import NaturalLanguage
func detectedLanguage(for string: String) -> String? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(string)
guard let languageCode = recognizer.dominantLanguage?.rawValue else { return nil }
let detectedLanguage = Locale.current.localizedString(forIdentifier: languageCode)
return detectedLanguage
}
Older versions (iOS 11+)
Briefly:
You could achieve it by using NSLinguisticTagger, as:
func detectedLanguage<T: StringProtocol>(for string: T) -> String? {
let recognizer = NLLanguageRecognizer()
recognizer.processString(String(string))
guard let languageCode = recognizer.dominantLanguage?.rawValue else { return nil }
let detectedLanguage = Locale.current.localizedString(forIdentifier: languageCode)
return detectedLanguage
}
Details:
First of all, you should be aware of what are you asking about is mainly relates to the world of Natural language processing (NLP).
Since NLP is more than text language detection, the rest of the answer will not contains specific NLP information.
Obviously, implementing such a functionality is not that easy, especially when starting to care about the details of the process such as splitting into sentences and even into words, after that recognising names and punctuations etc... I bet you would think of "what a painful process! it is not even logical to do it by myself"; Fortunately, iOS does supports NLP (actually, NLP APIs are available for all Apple platforms, not only the iOS) to make what are you aiming for to be easy to be implemented. The core component that you would work with is NSLinguisticTagger:
Analyze natural language text to tag part of speech and lexical class,
identify names, perform lemmatization, and determine the language and
script.
NSLinguisticTagger provides a uniform interface to a variety of
natural language processing functionality with support for many
different languages and scripts. You can use this class to segment
natural language text into paragraphs, sentences, or words, and tag
information about those segments, such as part of speech, lexical
class, lemma, script, and language.
As mentioned in the class documentation, the method that you are looking for - under Determining the Dominant Language and Orthography section- is dominantLanguage(for:):
Returns the dominant language for the specified string.
.
.
Return Value
The BCP-47 tag identifying the dominant language of the string, or the
tag "und" if a specific language cannot be determined.
You might notice that the NSLinguisticTagger is exist since back to iOS 5. However, dominantLanguage(for:) method is only supported for iOS 11 and above, that's because it has been developed on top of the Core ML Framework:
. . .
Core ML is the foundation for domain-specific frameworks and
functionality. Core ML supports Vision for image analysis, Foundation
for natural language processing (for example, the NSLinguisticTagger
class), and GameplayKit for evaluating learned decision trees. Core ML
itself builds on top of low-level primitives like Accelerate and BNNS,
as well as Metal Performance Shaders.
Based on the returned value from calling dominantLanguage(for:) by passing "The quick brown fox jumps over the lazy dog":
NSLinguisticTagger.dominantLanguage(for: "The quick brown fox jumps over the lazy dog")
would be "en" optional string. However, so far that is not the desired output, the expectation is to get "English" instead! Well, that is exactly what you should get by calling the localizedString(forLanguageCode:) method from Locale Structure and passing the gotten language code:
Locale.current.localizedString(forIdentifier: "en") // English
Putting all together:
As mentioned in the "Quick Answer" code snippet, the function would be:
func detectedLanguage<T: StringProtocol>(_ forString: T) -> String? {
guard let languageCode = NSLinguisticTagger.dominantLanguage(for: String(forString)) else {
return nil
}
let detectedLanguage = Locale.current.localizedString(forIdentifier: languageCode)
return detectedLanguage
}
Output:
It would be as expected:
let englishDetectedLanguage = detectedLanguage(textEN) // => English
let spanishDetectedLanguage = detectedLanguage(textES) // => Spanish
let arabicDetectedLanguage = detectedLanguage(textAR) // => Arabic
let germanDetectedLanguage = detectedLanguage(textDE) // => German
Note That:
There still cases for not getting a language name for a given string, like:
let textUND = "SdsOE"
let undefinedDetectedLanguage = detectedLanguage(textUND) // => Unknown language
Or it could be even nil:
let rubbish = "000747322"
let rubbishDetectedLanguage = detectedLanguage(rubbish) // => nil
Still find it a not bad result for providing a useful output...
Furthermore:
About NSLinguisticTagger:
Although I will not going to dive deep in NSLinguisticTagger usage, I would like to note that there are couple of really cool features exist in it more than just simply detecting the language for a given a text; As a pretty simple example: using the lemma when enumerating tags would be so helpful when working with Information retrieval, since you would be able to recognize the word "driving" passing "drive" word.
Official Resources
Apple Video Sessions:
For more about Natural Language Processing and how NSLinguisticTagger works: Natural Language Processing and your Apps.
Also, for getting familiar with the CoreML:
Introducing Core ML.
Core ML in depth.
You can use NSLinguisticTagger's tagAt method. It support iOS 5 and later.
func detectLanguage<T: StringProtocol>(for text: T) -> String? {
let tagger = NSLinguisticTagger.init(tagSchemes: [.language], options: 0)
tagger.string = String(text)
guard let languageCode = tagger.tag(at: 0, scheme: .language, tokenRange: nil, sentenceRange: nil) else { return nil }
return Locale.current.localizedString(forIdentifier: languageCode)
}
detectLanguage(for: "The quick brown fox jumps over the lazy dog") // English
detectLanguage(for: "El zorro marrón rápido salta sobre el perro perezoso") // Spanish
detectLanguage(for: "الثعلب البني السريع يقفز فوق الكلب الكسول") // Arabic
detectLanguage(for: "Der schnelle braune Fuchs springt über den faulen Hund") // German
I tried NSLinguisticTagger with short input text like hello, it always recognizes as Italian.
Luckily, Apple recently added NLLanguageRecognizer available on iOS 12, and seems like it more accurate :D
import NaturalLanguage
if #available(iOS 12.0, *) {
let languageRecognizer = NLLanguageRecognizer()
languageRecognizer.processString(text)
let code = languageRecognizer.dominantLanguage!.rawValue
let language = Locale.current.localizedString(forIdentifier: code)
}

How to generate random number without repeating in Swift

I'm extremely new to Swift and programming in general so please be patient with me while I'm trying to get the hang of this.
I've been following a beginners course in Swift from Treehouse and managed to develop a simple app that generates random quotes. So far so good. Now before moving on to more advanced lessons I figured I'd try to update the existing app just to make sure I get some solid practice before moving on.
So here's my question: I've managed to generate a random number through the GameKit framework, but the problem is that sometimes quotes appear consecutively. How can I avoid this from happening?
Here's my code:
import GameKit
struct FactProvider {
let facts = [
"Ants stretch when they wake up in the morning.",
"Ostriches can run faster than horses.",
"Olympic gold medals are actually made mostly of silver.",
"You are born with 300 bones; by the time you are an adult you will have 206.",
"It takes about 8 minutes for light from the Sun to reach Earth.",
"Some bamboo plants can grow almost a meter in just one day.",
"The state of Florida is bigger than England.",
"Some penguins can leap 2-3 meters out of the water.",
"On average, it takes 66 days to form a new habit.",
"Mammoths still walked the Earth when the Great Pyramid was being built."
]
func randomFact() -> String {
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: facts.count)
return facts[randomNumber]
}
}
You can store last random number or last fact in a variable and check it in your randomFact function. Like this:
var lastRandomNumber = -1
func randomFact() -> String {
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: facts.count)
if randomNumber == lastRandomNumber {
return randomFact()
} else {
lastRandomNumber = randomNumber
return facts[randomNumber]
}
}

how to use calculated values from past steps to determine next step

I'm working on a Survey app based on ResearcKit, where I need to determine the next step based on the sum of the results of the last five steps. This is my very first time programming in swift, and it has been a while since I've done OOP, and I keep making rookie mistakes. Anyway:
In each those five steps, the user chooses one of three sentences that fits her situation the best. Each of these choices results in an answervalue (0, 1 or 2)
If the sum of the answervalues <= 5 the next step is a completionstep (no significant reason for worry), if the sum > 5 they will get a completionstep with tips on what steps to take for help.
A simplified piece of code (with only two steps to sum up) shows where my problem is - it seems like I'm doing something stupid there. Google helped me a lot with all the other predicates for my Survey, mostly with the NSCompundPredicate, but rewriting this to a situation where I could use that seems like the (very) long way around a seemingly simple problem.
Any help is greatly appreciated.
...
let choices = [
ORKTextChoice(text: “never”, value: "0" as NSCoding & NSCopying & NSObjectProtocol),
ORKTextChoice(text: “sometimes”, value: "1" as NSCoding & NSCopying & NSObjectProtocol),
ORKTextChoice(text: “all the time”, value: "2" as NSCoding & NSCopying & NSObjectProtocol)]
 
let question1AnswerFormat : ORKTextChoiceAnswerFormat = ORKAnswerFormat.choiceAnswerFormat(with: .singleChoice, textChoices: choices)
let question1 = ORKQuestionStep(identifier: "question1", title: “question1”, answer: question1AnswerFormat)
question1.isOptional = false
question1.text = “Do you ever visit StackOverflow?”
steps += [question1]
    
let question2AnswerFormat : ORKTextChoiceAnswerFormat = ORKAnswerFormat.choiceAnswerFormat(with: .singleChoice, textChoices: choices)
let question2 = ORKQuestionStep(identifier: "question2", title: “question2”, answer: question2AnswerFormat)
question2.isOptional = false
question2.text = “Do you ever post questions on StackOverflow?”
steps += [question2]
//This part is rubbish, it doesn’t even compile, but I hope this shows what I’m looking for
let sum :Int = Int(ORKResultSelector(resultIdentifier: question1.identifier) as! String)! + Int(ORKResultSelector(resultIdentifier: question2.identifier) as! String)!
// ===
let predicate = NSPredicate(value: (sum>2))
let rule = ORKPredicateStepNavigationRule(resultPredicatesAndDestinationStepIdentifiers: [(resultPredicate: predicate, destinationStepIdentifier: risk.identifier)], defaultStepIdentifierOrNil: norisk.identifier)
task.setNavigationRule(rule, forTriggerStepIdentifier: question2.identifier)
...

iOS Game Center Combined Leaderboard Loading

Question:
When loading scores from a combined leaderboard, how do I tell which source leaderboard the score originated from?
Background:
I am new to using iOS Game Center. I currently have three leaderboards; let's call them "level1", "level2" and a combined one called "aggregate". I submit scores like this, and it seems to work:
let score = GKScore(leaderboardIdentifier: "level1", player: localPlayer)
score.value = // Score here...
score.context = // Context here...
GKScore.reportScores([gcScore]) { error in
// Error handling...
}
When I query to find a list of the top ten scores on all levels, I do this:
var leaderboard = GKLeaderboard()
leaderboard.identifier = "aggregate"
leaderboard.range = NSRange(location: 1, length: 10)
leaderboard.loadScoresWithCompletionHandler() { objects, error in
// Error handling removed...
let scores = objects as? [GKScore]
// Examine the scores, looking at each score.leaderboardIdentifier to
// determine where it originally came from.
}
Unfortunately, the leaderboardIdentifier on each score has the value "aggregate". I'm not sure if I'm doing something wrong or if I'm missing something, but my understanding of the leaderboard documentation makes it sound like this should be set to the original leaderboard value.
Any thoughts?

Resources