Recent

Author Topic: [SOLVED] iOS: GetAppConfigDir not working?  (Read 5639 times)

tk

  • Sr. Member
  • ****
  • Posts: 361
    • tkweb
[SOLVED] iOS: GetAppConfigDir not working?
« on: December 13, 2016, 04:07:50 pm »
Hi, I run a Xamarin app on iPad with FPC built library added as local embedded framework, with free commisioning (http://forum.lazarus.freepascal.org/index.php/topic,34431.0.html).

The app already runs fine but I cannot save library settings to a location returned by GetAppConfigDir. On IPhone Simulator it is working.

Now it returns following directory (I try to write my configuration there):
Code: [Select]
/private/var/mobile/Containers/Data/Application/{GUID}/.config
Interesting is that I can save the settings from main Xamarin app (which uses package Xam.Plugins.Settings, I don't know the path where it saves these).

Is the path wrong for iOS (I remember having similar problem with Android but it has been fixed in the trunk)? If yes what is the correct path?

Using now Free Pascal from trunk.

Thank you
« Last Edit: December 20, 2016, 11:52:43 am by tk »
Lazarus 1.7 with FPC 3.1.1.

http://www.tkweb.eu/

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: iOS: GetAppConfigDir not working?
« Reply #1 on: December 13, 2016, 04:37:38 pm »
The app already runs fine but I cannot save library settings to a location returned by GetAppConfigDir. On IPhone Simulator it is working.

I would use the standard iOS approach, which is probably what Xamarin uses. Eg, NSUserDefaults would be the class to look at. See the NSMisc.pas unit in nsunits-src.zip here:

https://macpgmr.github.io/

I would not trust things like GetAppConfigDir. Historically this function's result made sense on Linux, but not OS X (much less iOS).

Your app runs find on Simulator because it's executing on OS X, where you have write access to more places.

Is there some reason why both the app and the library save settings? I would think only the app should do that.

tk

  • Sr. Member
  • ****
  • Posts: 361
    • tkweb
Re: iOS: GetAppConfigDir not working?
« Reply #2 on: December 13, 2016, 05:15:49 pm »
I would use the standard iOS approach, which is probably what Xamarin uses. Eg, NSUserDefaults would be the class to look at.

Thanks Phil. I'll look at that.

I would not trust things like GetAppConfigDir. Historically this function's result made sense on Linux, but not OS X (much less iOS).

Actually it works fine for us on Win, Linux, OSX and Android. According to Free Pascal docs, it is meant to get platform independent saving location:
http://www.freepascal.org/docs-html/rtl/sysutils/getappconfigdir.html

Is there some reason why both the app and the library save settings? I would think only the app should do that.

The library must/should save specific intermediate data to run faster on next launch. We don't want to burden its users with that. It would not be easily possible anyway.

EDIT:
Actually NSUSerDefaults appears to be meant only for storing small strings and not big binary files. I need to store bigger binary files (cached data). The correct location should be
Code: [Select]
<Application_Home>/Library/Caches according to:
https://developer.apple.com/icloud/documentation/data-storage/index.html.
But how to determine <Application_Home>?
« Last Edit: December 13, 2016, 06:19:52 pm by tk »
Lazarus 1.7 with FPC 3.1.1.

http://www.tkweb.eu/

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: iOS: GetAppConfigDir not working?
« Reply #3 on: December 13, 2016, 06:39:15 pm »
The library must/should save specific intermediate data to run faster on next launch. We don't want to burden its users with that. It would not be easily possible anyway.

I would not call that settings (preferences), so you probably want to use the Library/Cache folder in the app's home folder.

This article is 5 years old, but I believe the folder structure is still the same:

https://macpgmr.github.io/ObjP/ObjP_Part5.html#The%20Sandbox

As always, with iOS it's important to do things the iOS way. There should be an NS method that provides this location. See NSMisc.pas for a function that returns the Documents folder; write something similar to that for Library/Caches.

Note that any "config" path returned by GetAppConfigDir that contains a hidden directory (dot) is probably _not_ a proper folder to use with OS X or iOS. It may happen to work on OS X because OS X supports many of the Unix conventions and locations, but you won't find modern OS X apps using these locations, certainly not for preferences.

tk

  • Sr. Member
  • ****
  • Posts: 361
    • tkweb
Re: iOS: GetAppConfigDir not working?
« Reply #4 on: December 13, 2016, 06:59:59 pm »
Thanks again Phil.
For OSX, I got the solution with, added to NSMisc.pas:

Code: Pascal  [Select]
  1. function GetCachePath : string;
  2. var
  3.   paths : NSArray;
  4. begin
  5.   paths := NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, True);
  6.   Result := NSStrToStr(paths.objectAtIndex(0));
  7. end;
  8.  
  9.  

However, for IPHONESIM and DARWIN/ARM targets I cannot compile NSMIsc.pas:

Code: [Select]
NSMisc.pas(23,3) Fatal: Cannot find iPhoneAll used by NSMisc.
I can see this unit in cocoaint package but fpc clearly does not find that.
Should I add sth. to fpc.cfg?
Lazarus 1.7 with FPC 3.1.1.

http://www.tkweb.eu/

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: iOS: GetAppConfigDir not working?
« Reply #5 on: December 13, 2016, 07:14:44 pm »
However, for IPHONESIM and DARWIN/ARM targets I cannot compile NSMIsc.pas:

Code: [Select]
NSMisc.pas(23,3) Fatal: Cannot find iPhoneAll used by NSMisc.

I don't believe the iPhoneAll unit included with FPC has been updated in years. You should probably use Ryan's parsed iOS header files, either individual framework units or an equivalent iPhoneAll unit that includes several of the commonly used frameworks.

https://github.com/genericptr

CocoaAll unit included with FPC is also very old. If you find classes or methods that you want to use that are not in CocoaAll, then use Ryan's parsed OS X header files there too.

Edit: On second thought, another approach would be to determine the path on the Xamarin side and just pass it to your library. That would make sense if you don't need iPhoneAll anywhere else in the library.
« Last Edit: December 14, 2016, 12:59:32 am by Phil »

tk

  • Sr. Member
  • ****
  • Posts: 361
    • tkweb
Re: iOS: GetAppConfigDir not working?
« Reply #6 on: December 14, 2016, 03:30:28 pm »
Edit: On second thought, another approach would be to determine the path on the Xamarin side and just pass it to your library. That would make sense if you don't need iPhoneAll anywhere else in the library.

Already considered that as well, but finally this will be added only as option.

Actually the way through NSUnits/IphoneAll works well on simulator (and suppose on device it will work as well, can't test on device today).

EDIT: Now tested on iPad again and the cache path works fine there. Marking this as solved.
« Last Edit: December 20, 2016, 11:52:27 am by tk »
Lazarus 1.7 with FPC 3.1.1.

http://www.tkweb.eu/