問題
Mac/Windows向けのプラグインをJUCEを使って作ってきた人は、ファイルの読み書きにはまずjuce::Fileを使っていたと思うが、それはiOSではコケる。Sandbox内のファイルであればそれでも読めるのだが、Sandbox外のファイルの読み書きはできない。
解決方法
juce::URLを使う。とにかくURLを使わなければダメ。juce::FileChooserを使った例。
保存(Export)
MainComponent.cpp
juce::FileChooser chooser (juce::String("Export a file..."),
juce::String(),
juce::String());
if (chooser.browseForFileToSave(true))
{
auto result = chooser.getURLResult();
juce::String textToSave = "Hello!";
#if 1 // 正常に保存できる
std::unique_ptr<juce::OutputStream> os = result.createOutputStream();
#else // 保存できない。URLからgetLocalFile()でFileを取得するのはNG。
juce::File file = result.getLocalFile();
std::unique_ptr<juce::OutputStream> os = file.createOutputStream();
#endif
auto ret = os->writeString(textToSave);
if (!ret)
{
juce::AlertWindow::showMessageBox(juce::AlertWindow::WarningIcon, "Failed to write text to file.", "");
}
}
読み込み(Import)
MainComponent.cpp
juce::FileChooser chooser (juce::String("Select the program file to import..."),
juce::String(),
juce::String());
if (chooser.browseForFileToOpen())
{
auto result = chooser.getURLResult();
#if 1 // 読み込める。
std::unique_ptr<juce::InputStream> is = result.createInputStream(false);
#else // 読み込めない。URLからgetLocalFile()でFileを取得するのはNG。
juce::File file = result.getLocalFile();
std::unique_ptr<juce::InputStream> is = file.createInputStream();
#endif
juce::String text = is->readString();
if (text.isNotEmpty())
{
labelText->setText(text, juce::dontSendNotification);
}
else
{
juce::AlertWindow::showMessageBox(juce::AlertWindow::WarningIcon, "Failed to read text from file.", "");
}
}
他OSとの互換性
Mac/Windowsでも正常に動くので、ファイルは常にjuce::URLで扱えばよいと思う。