0

I'm developing a game which is almost done so I've come to a point where I have to store the user's highscore locally. What is the most secure way of storing the highscore in a game? Some suggest that NSUserDefaults is not a secure way as users can manipulate their highscore e.g when they jailbreak.

I'm a newbie to Spritekit programming so can you please advice the best way of storing the highscore which is not too complicated. If you provide an example also then it would be great, otherwise it's fine.

Thanks

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
ah786
  • 61
  • 6
  • 1
    NSUserDefaults would be the easiest, otherwise use coreData – Steve Feb 03 '15 at 19:02
  • NSKeyed[Un]Archiver can be used, you have a gameData object which is encoded and written to a file in your app bundle. –  Feb 03 '15 at 19:30
  • http://stackoverflow.com/questions/25420651/store-string-in-nsuserdefaults-swift – sangony Feb 03 '15 at 21:14
  • 2
    Against a jailbroken device, this is not a solvable problem. You can do something simple to obfuscate (hide) it. You can do something complicated. Both will be broken (so simple is usually better). Lots of previous discussion on other versions of this problem: http://stackoverflow.com/questions/9181186/secure-https-encryption-for-iphone-app-to-webpage http://stackoverflow.com/questions/9448632/best-practices-for-ios-applications-security/9448821#9448821 – Rob Napier Feb 03 '15 at 21:19
  • I'm using NSUserDefaults. It is 4 lines of code. Core Data is overkill for something this simple. Alternatively you can use Parse.com for authenticated users it has the benefit of network storage and local caching. Or finally you can use Apple's GameKit. I don't like this as a user, but you might. – Patrick Collins Feb 03 '15 at 22:53
  • 1
    use Game Center - storage is as safe as can be, but of course what you actually *send* over could have already been tampered with. That problem you'll always be facing. – CodeSmile Feb 04 '15 at 09:18
  • Thank you for the answers! I'll check them out... – ah786 Feb 04 '15 at 18:41
  • Here is one good article about everything you asked :http://resources.infosecinstitute.com/ios-application-security-part-20-local-data-storage-nsuserdefaults-coredata-sqlite-plist-files/ Also there is no answer in that article which offers you 100% secure way. It's more like that you have to follow the lesser evil principle :) – Whirlwind Feb 05 '15 at 13:15
  • @Whirlwind thanks, will read it... – ah786 Feb 05 '15 at 14:19
  • @Whirlwind Wow just ready it and it's very useful... Thanks! – ah786 Feb 05 '15 at 14:24

1 Answers1

4

You can't protect your score against jailbreak-users. Because they sometimes even can manipulate the highscore before uploading it to gamecenter etc.

Also the effort has to match the result. You could make a CoreData-DB to save three numbers. But it would be an overkill. You'd have to write a huge amount of code to save one number.

So I think for most games without complex systems with items, choices etc. it's mostly okay to use NSUserDefaults.

So I would keep it simple and use NSUserDefaults

func saveHighscore(highscore:Int){

    //Check if there is already a highscore
    if let currentHighscore:Int = NSUserDefaults.standardUserDefaults().valueForKey("highscore") as? Int{
        //If the new highscore is higher then the current highscore, save it.
        if(highscore > currentHighscore){
            NSUserDefaults.setValue(highscore, forKey: "highscore")
        }
    }else{
        //If there isn't a highscore set yet, every highscore is higher then nothing. So add it.
        NSUserDefaults.setValue(highscore, forKey: "highscore")
    }
}
Christian
  • 22,585
  • 9
  • 80
  • 106
  • Firstly, thanks for your answer. My other question is for instance, if I want to save the total coins the user has collected, do you think I should use NSUserDefaults for that too? – ah786 Feb 04 '15 at 18:36
  • Absolutely. I will add an explanation. But short: If it's something simple, like some numbers, store it in NSUserdefaults. – Christian Feb 04 '15 at 18:37
  • I've added the explanation. If that answered your question it would be great if you could accept the question by clicking on the tick on the left side so that other people can find the answer easier. – Christian Feb 04 '15 at 18:41
  • I see. Thanks. I will accept it, but in the else statement, I don't understand why you are saving the highscore in the NSUserDefaults? Isn't the else statement run only when the current score is less than the highscore? If so, it shouldn't save the score right? – ah786 Feb 04 '15 at 18:46
  • No. As you see, the if which checks if the highscore is more then the current score is a nested if. the 'else' is for the first if. I will add comments. – Christian Feb 04 '15 at 18:47
  • I just tried your code and it crashes my app. Any reason why it happens although you are checking if there's already a value for the highscore or not. – ah786 Feb 08 '15 at 11:27