UserDefaults.standard.set() not working on watchOS only - ios

I have a watchOS only app (not my first) and using UserDefaults.standard.set() to store some data. In my other project it is working fine but in this project it do not store anything. Values to store are present (Array). Even after triggering UserDefaults.standard.synchronize() which is not needed on my other app it do not work. Any suggestions on which factors it can be possible to not work?
After rebuilding / running the app from XCode the data is gone.
Just saving like that
UserDefaults.standard.set(self.data, forKey: "fetchData")
UserDefaults.standard.synchronize()
Where self.data is an Array with items of type Dictionary<String,Any> (Int and Date get stored)

Related

Userdefaults from old swift app to new ionic app

I've maintained an iOS app developed in swift for few months but now I'm ready to change it with a newly developed app in ionic. I'm facing a problem with reading userdefaults in the new app.
In the old app I used this piece of code to store in userdefaults:
UserDefaults.standard.set("ciao", forKey: "prova")
And in the new app I use capacitor storage plugin to try to retrieve the old properties with this piece of code:
const prop = await Storage.get({ key: 'prova' });
this.retrievedProp = prop.value;
But the returned value is null
Any idea?
Thanks

iOS Locksmith cannot move stored data to from service "A" to service "B"

In one of my iOS apps I'm developing I'm storing some info in the Keychain. To interact with the keychain I am using Locksmith (https://github.com/matthewpalmer/Locksmith)
In version v1 of my app, I was writing some data in the keychain by using
Locksmith.saveData(data: data, forUserAccount:"A1", inService: "S1")
Now, in v2, I realized that I would like to migrate my data from "S1" to "S2", so I've set on to writing a small migration script to achieve this.
Essentially, what I am doing:
// read the old data
if let d = Locksmith.loadDataForUserAccount(userAccount: "A1", inService: "S1") {
// write it in a new location
Locksmith.saveData(data: d, forUserAccount: "A1", inService: "S2")
}
This is an oversimplification of my code.
The problem is that d = nil every time, although I know for sure it exists (when I am building the v1 of the app, I can see the data exists in that location).
Any ideas on this? Did somebody run into this problem before?
Some tech specs:
Xcode 8.3
Swift 3.1
Locksmith 3.0 (via Carthage)
iOS Simulator (iPhone 6s) running iOS 10.3
Didn't try on a real device.

UserDefaults - not saving consistently when using Xcode Simulator

I am learning iOS development and I have stumbled across an issue where UserDefaults doesn't seem to be consistently saving correctly.
When I open the app, it checks to see if a UserDefaults property exists, if so, it does something. Now, if I save the UserDefaults property and 'synchronize', then press stop on the simulator and then press 'play' again to re-open it, sometimes the UserDefaults value is nil.
I have yet to test this on a physical device, but has anyone had the same issue - if so, is it expected?
Maybe UserDefaults work fine but when you save some data to UserDefaults and rebuild or run use Command + R if already running simulator
then sometimes nothing changed (saved data disappear)
so everytime when this situation(have to save some data to UserDefaults , CoreData or Realm) I stop and exit simulator first and rebuild or run Xcode
it works fine to me

iOS Keychain Value Nil

I'm using this iOS library to handle storing and getting values in the iOS Keychain. Below is the main code I'm using to store a value in the keychain.
let email: String = emailTextField.text!
let keychain = KeychainSwift()
keychain.set(email, forKey: "email")
I'm trying to set values in the keychain to store the users email and password. The code above is only for email. Right after that code I have set a breakpoint and running p keychain.get("email") returns nil in the console. p keychain.lastResultCode returns -25300. Even after trying to quit the app and get the data again it still doesn't seem to be working. Any ideas why it would be returning nil? Just for reference I'm using the iPhone Simulator running Xcode 8.
You have to turn on Keychain Sharing capability in order for the simulator to work.
This seems to be a known bug. You can read up more on here.
https://forums.developer.apple.com/message/179846

Keychain access on watchOS 2 not working on the actual watch

I have read in the Apple developer forum that unlike watchOS 1, watchOS 2 does not share its keychain with the phone app so bam!! keychain sharing is not enabled by default we got to do a workaround for that.
Ok coming to my issue, I was trying to run a very basic keychain access program on the actual watch device running the latest beta (beta4) using a git library https://github.com/jrendel/SwiftKeychainWrapper
let saveSuccessful: Bool = KeychainWrapper.setString("keychainData", forKey: "ImportantKeychainData")
if saveSuccessful{
let retrievedString: String? = KeychainWrapper.stringForKey("ImportantKeychainData")
print(retrievedString)
}
else
{
print("unable to write keychain data")
}
On the simulator it works like a charm but when I try to run the same on the actual watch it gives me an status code of -34018
There was no public documentation about this error code but I did a little digging to find out it turned out to be
errSecMissingEntitlement = -34018, /* Internal error when a required entitlement isn't present. */
source: http://opensource.apple.com/source/Security/Security-55471/sec/Security/SecBasePriv.h
I did a lot of research actually a full day on this and people pointed me to various directions, like memory issues, entitlements, profile issue, bug in keychain etc.
The catch here is that most of the dev's who reported this issue did not have it continuously like I got it on every run of the app, they had it at certain places only like when app was in background etc. To summarise,
1. I tried the same piece of code on iOS 9 beta 4 and it worked well on the phone.
2. The same code works well on the watch simulator.
3. The same code does not work on watchOS beta 4 returns -34018 continuously on the device but works well on the simulator.
4. All this testing is done using free provisioning introduced from Xcode 7, entitlements were added to the phone app and the watch extension, keychain sharing was enabled, app groups was enabled.
My questions are
1. Am I missing something here that I have to do with the device keychain that I am supposedly doing it wrong?
2. Is there an issue with free provisioning?
3. Is there an issue with the keychain perhaps??
Any help is appreciated.
FYI I also tried Apple's KeychainItemWrapper, customs code directly talking to SecItem methods nothing turned out to be fruitful.
Update, I tried this as well it fails as usual
let storableString:NSString = "keychain in watchos is working with simple code"
let query : [NSString : AnyObject] = [
kSecClass : kSecClassGenericPassword,
kSecAttrService : "WatchService",
kSecAttrLabel : "KeychainData",
kSecAttrAccount : "SecureData",
kSecValueData : storableString.dataUsingEncoding(NSUTF8StringEncoding)!
]
let result = SecItemAdd(query, nil)
print(result)
Update 2: Issue has been fixed in watchOS2 beta 5.
Issue has been fixed by Apple in the recent watchOS 2 beta 5.

Resources