I've been pulling my hair out over this problem for two days now. I generate a small movie file in the iPhone App that I want to send from the iPhone to play on an Apple Watch. As I proof of concept, I put a similar .mov in the Bundle of the Apple Watch App and was able to play it with no problems. So I figured, easy peasy, now when I want to send a new little clip to the watch, I will just put it in an App Group Shared container and access it from there instead of from the Bundle. Nope!
I have been through tons of S.O. posts, tried many different approaches and nothing works as expected.
Before you ask, I have re-done the App Group several times, deleted the old ones from iTunes Connect, re-generated provisioning profiles, cleaned the targets numerous times, deleted the DerivedData several times, deleted the apps and started over several times and tried virtually every little tweak and fix I could find on S.O. Nothing helps.
I do think I know what the problem is, but have no idea how to conquer it.
Here is the code that I use in both the iPhone App and the Watch App to get a path to the shared container (this snippet if from the Watch side):
let fileManager = FileManager.default
let sharedContainer = fileManager
.containerURL(
forSecurityApplicationGroupIdentifier: "group.com.mycompany.myappname")
let dirPath = sharedContainer?.path
sharedFilePathOnWatch = (dirPath! as NSString).appendingPathComponent("watchPreview.mov")
print ("Shared File Path on Watch: \(sharedFilePathOnWatch)")
print ("Shared File Path from iPhone: \(sharedFilePath)")
The print statements show me the Shared file path that I send over to the watch from the iPhone (via Watch Connectivity) and the Shared Path that the Watch App resolves.
What I get when this runs it the following:
Shared File Path on Watch: /private/var/mobile/Containers/Shared/AppGroup/94AA7797-528D-4E96-9623-23285BE0742B/watchPreview.mov
Shared File Path from iPhone: /private/var/mobile/Containers/Shared/AppGroup/4D43C314-CCBD-4861-BF90-69A8AC71198C/watchPreview.mov
Now I was expecting that there would be only one shared container and that both the iPhone and the Watch should resolve the same path, but this is not the case. I've also noticed that these paths remain constant for the two apps over multiple runs. It's not a dynamic address that is changing every time I run as I suspected for awhile.
As a last ditch attempt to get this to function, I figured that since I had a path to the shared container on the iPhone and the shared container on the Apple Watch, maybe I could just move the file from one to the other because, well, they are supposed to be sharing. But no, even that doesn't work.
So the big questions are:
Why do I resolve two different paths on the shared Apps
How the heck do I get my little movie file from the iPhone to the Apple Watch
With the introduction of watchOS2 and native watchOS apps, Apple Watch apps are no longer just extensions of their iOS counterpart and hence they don't share AppGroups.
You cannot use AppGroups for sharing data from watchOS2 onwards. You have to use the WatchConnectivity framework for sending data between your iOS and watchOS apps.
See the Keeping your WatchOS content up-to-date page for more information on the topic.
Related
According to the App Programming Guide for watchOS it is possible to store data in a Documents folder in the watch app. My code also seems to be doing this sucessfull, as there are no errors.
However, to really debug this, i wonder if there is some way to access this data on the device through the GUI for debugging (e.g., iTunesFilesharing with UIFileSharingEnabled, downloading the Container).
I am working on a library with a very verbose logger module that, on iOS, writes xml logs to NSDocumentDirectory in a consistent file tree. I want to come up with a way for the user of this library to easily access these logs.
I know it is simple to programatically retrieve files from this directory, but is it possible to access this directory on an iOS physical device in any way from outside Xcode to retrieve these logs? I feel like I have seen it somewhere before, something in the manner of extracting the .ipa file and going into the package contents, but I could be wrong.
---------------------------------------------------------EDIT------------------------------------------------------------------
This (Browse the files created on a device by the IOS application I'm developing, on workstation?) is how to do it with Xcode on a device, but I have to assume that there is some way we can create that gets the logs off of a device for a user.
is it possible to access this directory on an iOS physical device in any way from outside Xcode to retrieve these logs?
It is possible to expose the Documents directory by enabling iTunes file sharing. When file sharing is enabled through this method, the contents of Documents directory would be visible to the user in iTunes, which can also be exported. The documents would also be visible for export through some third party desktop apps like iExplorer.
Here is the link to Apple documentation. You may also refer this thread to understand how this is done.
If you're using a simulator (apparently your task doesn't seem to need te real device) you are in luck.
You should go to a folder similar to this one:
/Users/[YOUR_USER_NAME]/Library/Developer/CoreSimulator/Devices/[RANDOM_HASH_YOU_SHOULD_DISCOVER]/data/Containers/Data/Application/[RANDOM_HASH_2_YOU_SHOULD_ALSO_DISCOVER]
Once there, with finder, you'll get the "documents" folder of the simulator and the app you're trying to retrieve your logs from.
You might say: I don't know which 2 RANDOM_HASHES should I go to.
Yes, you're right. If you have MANY simulators installed and or being used, it might be tricky to discover which one is the one you're trying to debug.
The same thing with your APP, your app will live in another RANDOM_HASH folder, and you should browse them, one by one, and then discover your documents folder.
Someone needed to solve this "mess" and created a Xcode Alcatraz Extension that leads you to the exact live simulator and APP you're debugging in any given moment, and then you don't need to guess which 2 random_hash paths you need to navigate to.
If Xcode + Alcartaz plugin extension manager is somewhat out of your reach, you might need to google it. It's not a difficult process.
PS: That magical Alcatraz Extension is named "XCodeWay" (in case you are brave enough to install Alcatraz onto your copy of XCode).
EDIT: Useful link to get Alcatraz: http://alcatraz.io/ Follow its easy instructions and you're done.
EDIT2: If Xcode cannot be used, then the last question in this other thread might come in handy: Browse the files created on a device by the IOS application I'm developing, on workstation?
(Still, an external application in your users machine will be needed )
I have an iPad app that downloads PDF and audio files. I though these might be in the .ipa file (I used this thread ipad - extract images from application?) but I didn't see anything there.
Is there some way to find where these might be stored on a Mac (after syncing)?
Normally in many apps the media files will be downloaded to documents directory of app, which is inside the sandbox for the app. Simply telling when you instal a app OS will create a sand box, and all the data will be inside this sand box and only that particular app will have access to this data. So you will not be able to copy data.
Hope this answers your question.
The IPA is an application only. Once it is installed on your iPad, it becomes a "package". It does contain the data within that package with some apps that store locally. There is no Apple supported way to get to this data directly. Think of it like this. The IPA is kind of like a blueprint for a program. Like a blueprint for a shelf, I could build the shelf but the books wouldn't be stored in the blueprint. Only the shelf. When you install the app, the iPad builds your "shelf".
I want to build an iCloud based app that runs on both the Apple platforms, iOS and Mac. The app will use UIDocument on iOS and NSDocument on Mac to have a document based synchronization model - documents created on iOS will be available on Mac and vice versa.
The particular problem I'm facing is that I want the same iCloud container on both the apps. XCode creates a default container for the app based on the App ID, which has to be different on both the apps because this seems to be an Apple requirement - no two apps can have the same app id even if they are on different platforms.
So I left the default created container alone and added another container on both the Mac app as well as the iOS app. The app seems to work fine, I can create a new file package in both the apps in the correct place, but I'm having 2 issues:
The container does not appear properly in the iCloud settings management screen. In the entitlements section in XCode, I named the container as com.mycompany.myapp.mycontainer in both the apps. In the settings screen in iOS (Settings -> General -> Usage -> Manage Storage -> Show All) my app is listed as "mycontainer" instead of the App's actual name as I expected. Is it possible to supply a name and icon in the App's Info.plist to make it list properly?
My NSMetadataQuery is not working properly. I had made the iOS app with the Empty Application template, so the Info.plist was not properly setup with the CFBundleDocumentTypes key but I figured that out and fixed it. For firing my NSMetadataQuery in the iOS app, I'm using:
[self.queryCloud setPredicate:[NSPredicate predicateWithFormat:#"%K like '*.myextension*'",NSMetadataItemFSNameKey]];
with the search scope set like this:
[self.queryCloud setSearchScopes:[NSArray arrayWithObjects:NSMetadataQueryUbiquitousDocumentsScope, NSMetadataQueryUbiquitousDataScope, nil]];
I run the query after establishing the container's URL, I get the started and finished gathering notifications, but never the update notification from the NSMetadataQuery. Unless I go ahead and create a new document. If I create the document then I get notifications for Update, but only in that session. Next time I start up the app, the same settings don't give me any update notifications from NSMetadataQuery.
What am I doing wrong? Any pointers to articles on creating an iCloud document app targeting both Mac and iOS would be much appreciated! Suggestions, thoughts are most welcome.
I don't know about your NSMetadataQuery issues, but adding a shared iCloud container is easy, as long as you get the gotcha:
Pick one app ID that will be your shared cloud container. Doesn't matter if iOS or Mac OS X, you need to publish this app and it must be approved from the Apple Review Team* before your iCloud container will be available to any other app. e.g.
com.company.myawesomeapp
Note that you must not use a container name after your app ID (com.company.myawesomeapp.cloudcontainer), just use your appID!
Pick a second app ID (doesn't really matter), and create your second app. Open up Xcode and enable iCloud in the Capabilites Pane. Then under "iCloud Container Identifiers", add the identifier of your first (published and approved!) app
com.company.myawesomeapp
That's it!
There's just this one catch and that's the bottom line:
In order to use a container, an app must be available and approved. Before approval no other app may access your container, because technically it only exists as soon as your app is approved. Actually, it doesn't have to be available in the AppStore, it just needs to be approved (can be on developer held release).
You can only use a (shared) iCloud container if your app is published and has been approved.
I'm currently working on an universal iOS application which has reached more than 100mb in size due to the heavy usage of video and sound files. I've implemented a solution for loading these assets at runtime (from a website) but I'd like to know if Apple approves of such actions.
The way it works now is this:
A bundle (with all the video and sound files) is created for each iOS device type: iPhone, iPhone Retina and iPad.
Then this bundle is zipped and uploaded to the server.
Depending on what device the app is installed on, the corresponding zip file is downloaded, saved to the Documents directory and then unzipped.
Finally the bundle is loaded with [NSBundle bundleWithPath: ]
This method works fine but I couldn't figure out by reading the docs if Apple may reject the app because of it? Thanks!
As long you are just moving around audio and video files, Apple won't have a problem.
But I would suggest (for the user's sake) breaking up the package a bit further so that the user doesn't have to suffer a 100MB download.
Perhaps include a few files so that users w/o internet can do something with your app.