MPMediaLibrary.DidChangeNotification not working - ios

This question is related to Xamarin.iOS.
I have been trying since many days to get MPMediaLibrary.Notifications.ObserveDidChange to work without success. I tried almost everything. Suspecting something bad with Objective-C binding, I tried direct objc calls too using Messaging API. Finally, I built a Native Library and made sure that it works by testing it with pure objective-c app. Native one with Objective-C works without problem. However, the same Library when used with Xamarin.iOS doesn't get MPMediaLibraryDidChangeNotification. I have created in-built selector etc within Native library so that I just call a 'C' function without argument and it works with objective-c app. However, when used with Xamarin, the same doesn't work. I have taken care of calling beginGeneratingLibraryChangeNotifications().
Some people may suspect that My selector/delgate is not being called because of wrong use. However, every other notification is able to call my selector except this one. So syntax is not an issue, I suppose.
After all the efforts, I presume that there is something wrong in Xamarin settings, which is stopping me from getting MPMediaLibraryDidChangeNotification . I really dont know what exactly is it. So my question is - Can you guys get this notification ?
My test phone - iPhone6-8.0.2, Xamarin Studio Version 5.5.3 (build 6) Installation UUID: d84b8c6d-f992-4f19-8a35-c14bcd08420e Runtime: Mono 3.10.0 ((detached/e204655) GTK+ 2.24.23 (Raleigh theme) Package version: 310000023 Apple Developer Tools Xcode 6.1 (6604) Build 6A1052d Xamarin.iOS Version: 8.4.0.16 (Indie Edition) Hash: 80e9ff7 Branch: Build date: 2014-10-22 15:09:12-0400
Thanks, Vinay

For the Record, I am posting the answer.
Since 64 bit transition, The MediaLibrary change notification is stopped for 32 bit apps. If you build your app for 64 bit iOS, everything is fine. However, 64 bit devices with 32 bit applications won't receive these notification. I have tested it thoroughly on iPhone6. So I think this is iOS bug, which Apple needs to rectify. All the Music Player applications on App Store are unable to update library anymore since they are 32 bit.
For Xamarin Users, use Unified API for proper notification support.

Related

iOS 13 - FileManager url(forPublishingUbiquitousItemAt:expiration:) not working anymore

I've developed an iOS app that uses the url(forPublishingUbiquitousItemAt:expiration:) method of Apple's FileManager class. Starting with the first Beta of iOS 13 this function stopped working and now it throws an error, stating "This code has been removed. You should switch off of this SPI". But I can't find anything related to this function neither in the release notes of iOS nor in the documentation for this function, and it even states there that it would be supported on Mac Catalyst 13.0+.
This also has nothing to do with Xcode 10 and 11, as it occurs when the app is built using either one of those versions.
Does anyone of you know more about that? It would be great to get new information on that.
Thanks,
Fabian.
This is fixed in iOS 13 beta 6. Updated today and this error magically disappeared!
Had my mind blown when I saw this error message.

appcelerator iOS application error with geolocation module

We are developing app for iOS and Android and we are using Ti.Gelocation to getCurrentPosition and then set the Region of the MapView of ti.map module.
The app is already on marketplace and downloaded, so we are developing an important upgrade with this new feature. We dont't have problem with Android platform, but with iOS version of the app we get a several error invoking Ti.Geolocation module
The error on iOS 9.x on iPad and iPhone (we have no test on iPod) is:
-[__NSCFString containsObject:] unrecognized selector sent to instance 0x1463d500 at GeoView.js (line xxxx)
This error happens with the project with it.vocami.vocamiapp app-id, in the test project (ap-id=it.vocami.vocamitest) that we use for research and test of new features, no error happens and all run good. When we add at every level of our code (in the first row too), for example, Ti.Geolocation.locationServiceEnabled, in the main vocamiapp project, we get the error.
We have tried all we could think but at the end, if we change the app-id, the code runs otherwise we get the error. We cannot change the app-id because we need to update our published app.
We are developing with AppceleratorStudio version 4.5.0.021602170281 and Ti SDK ver 5.2.0GA on Mac OS X 10.10.5.
I just recently was "hit" by the fact that when I made my app ready for Google Play I use a specific key/user to sign it with. That behaves differently from just running it locally on the phone.
I had to make sure that I had registered two certificates with Google's API in the developer console. It didn't give me exactly the message that you show - but wouldn't show the map with a location. And the way I read the location prior to showing it on the map led me in the wrong direction looking at permissions on Android first :-)
/John

IOMobileFramebufferGetLayerDefaultSurface not working on iOS 9

My main question is, how can I reverse engineer a private API function that already exists, but has been modified in a new version of iOS?
I have created an iOS application to record the screen content using IOSurface and IOMobileFramebuffer. The main functions the framebuffer use to open it are IOMobileFramebufferGetMainDisplay(connect) and IOMobileFramebufferGetLayerDefaultSurface.
These functions have been used since the very first version of the app, and they have worked on all versions of iOS 7 and 8. However, on the latest iOS 9 beta, which is beta 5, the function IOMobileFramebufferGetLayerDefaultSurface does not work. The function does not return 0, as it should when it successfully opens the framebuffer.
This other user on StackOverflow seems to also be experiencing the same issue: IOMobileFramebufferGetLayerDefaultSurface function failed on iOS 9. We have a reference to IOMobileFramebufferConnection named “_framebufferConnection” and an IOSurfaceRef named “_screenSurface” Here is the current code:
IOMobileFramebufferGetMainDisplay(&_framebufferConnection);
IOMobileFramebufferGetLayerDefaultSurface(_framebufferConnection, 0, &_screenSurface;
As stated before, these work perfectly on iOS 7-8, but on iOS 9, the second function crashes. I have also looked at the binaries with the symbols for both versions and compared them. The second parameter of the LDR is slightly different in iOS 9, when compared to the iOS 8.4.1 binary. So, back to the main question, how can I reverse engineer IOMobileFramebufferGetLayerDefaultSurface, or see how in what way it’s actually been modified on iOS 9?
To answer the question of "how in what way it’s actually been modified on iOS 9", I did some digging into IOMobileFramebufferGetLayerDefaultSurface on iOS8 vs iOS9 (GM). Here are the results of what I found:
Setup:
IOMobileFramebufferRef fb;
IOMobileFramebufferGetMainDisplay(&fb);
iOS8 Implementation:
Calls through to kern_GetLayerDefaultSurface
Which accesses underlying IOConnection
io_connect_t fbConnect = *(io_connect_t *)((char *)fb + 20)
To retrieve the IOSurfaceID via
IOSurfaceID surfaceID;
uint32_t outCount = 1;
IOConnectCallScalarMethod(fbConnect, 3, {0, 0}, 2, &surfaceID, &outCount)
Returns IOSurfaceLookup(surfaceID)
iOS9 Implementation:
Same steps as above aside from the return
Then tries to retrieve a mach port to access the surface via
io_service_t fbService = *(io_service_t *)((char *)fb + 16)
mach_port_t surfacePort;
IOServiceOpen(fbService, mach_task_self(), 3, &surfacePort)
On success, return IOSurfaceLookupFromMachPort(surfacePort)
It is on the last step that IOServiceOpen returns error 0x2c7 (unsupported function). Notice that the 3rd argument specifying the type of connection is 3 instead of the usual 0 when opening the framebuffer service. It is almost certain that this new connection type has permissions restrictions that prevent anyone but Apple from retrieving a mach port to access the IOMFB surface.
What's somewhat interesting is that the call to IOConnectCallScalarMethod still works to retrieve the ID of the IOMFB surface. However, it can no longer be accessed using IOSurfaceLookup because the surface is no longer global. It's a little surprising that it was global in the first place!
Hope this helps demystify why IOMFB can no longer be used to record the screen.
Source: My own use of LLDB with an iPhone6 running iOS 8.4 and an iPhone6+ running iOS9 GM
I believe #nevyn is correct. However, I would like to elaborate a bit more. I have looked into this exact issue extensively, and the IOMobileFramebufferGetLayerDefaultSurface function does return -536870201, while it should return 0 if it runs the function without any problems. This error is on the internet, but it only appears when users encounter generic problems with QuickTime. It could be that Apple has indeed locked up the framework completely, and needs an Apple-only entitlement to access the framebuffer. We cannot add these entitlements, since it also has to be on the provisioning profile. I currently am trying to read and interpret the disassembly and doing some reverse engineering work on the IOMobileFramebuffer binary to see if any of the parameters have changed since the last iOS version. I will surely update this answer if I discover anything. But if this is the case, I would suggest trying to find another method of trying to capture/record the screen content.
-UPDATE-
It seems as if there is evidence that this would be the case, if you read this, it shows the exact same error code, and it means that the function is "unsupported", and returns an IOKit error. At least we know what this means now. However, I am still unsure of how to fix it, or to make the function work. I will continue looking into this.
UPDATE 2
I have actually discovered a brand new class in iOS 9, "FigScreenCaptureController", and it is part of the MediaToolbox framework! What the strange thing is though, is why would Apple include this only in iOS 9? So, maybe there will be a way to record the display through this...I will be looking into this class more in depth very soon.
Not entirely correct - it's just a matter of an entitlement, as you can see if you dump the kext:
$ jtool -d __TEXT.__cstring 97.IOMobileGraphicsFamily.kext | grep com.apple
0xffffff80220c91a2: com.apple.private.allow-explicit-graphics-priority
If you self sign (jtool --sign --ent) with this , everything works well.
This does mean that on non-JB devices you can't use it. But with a jailbreak the immense power is in your hands once more.
IOMobileFramebuffer is completely locked down on iOS 9 and cannot be used from non-Apple apps anymore. AFAICT, this closes the last private API to capture the screen efficiently. ReplayKit is the only replacement, but does not allow programmatic access to the actual video data.

IBM Worklight Application Center iOS unresponsive to touch events

After successfully building and deploying the IBMAppCenter project, when attempting to download the IBM Application Center on iOS devices, there is no response when clicking on the actual installer link. This occurs on both real devices and through the simulator. Android application seems to be working just fine. I've provided a picture here showing some of the errors messages that we're seeing when clicking on 'IBM App Center iOS', as well as provided a subset of them below (http://i.imgur.com/vLrhVjT.jpg):
Deprecated attempt to access property 'changedTouches' on a non-TouchEvent object.
Deprecated attempt to access property 'target' on a non-Event object.
TypeError: undefined is not an object (evaluating 'a.target.getAttribute')
...
Deprecated attempt to access property 'which' on a non-UIEvent object.
App Center Console version 6.2.0.00-20140613-0730
IBM Worklight Studio version 6.2.0.1
Any idea what may be causing this, and how we can correct it? Thanks!
Make sure you are using a recent iFix of Worklight 6.2.0.x containing required Dojo fixes in order to add support for iOS 8 (which you are likely attempting to use the app on).
You can review the following tech note for instructions on downloading and installing the iFix: http://www-01.ibm.com/support/docview.wss?uid=swg21684538

Reminder API in iOS 6.0

Strange bug in iOS 6.0 sdk. Apple promised to deliver full reminder support via api, to allow thirdparty applications to read and write reminders on behalf of user. There is new methods in SDK to init storekit for use with reminders.
But seems like main method to make it possible - just not present. Both GM version of XCode 4.5 and simulator/ios-6 upgraded device shows that EKEventStore:initWithAccessToEntityTypes is not present in SDK and attempt to call it on device/simulator crashing application with
Error invoking method 'EKRemsIsGranted' on 'CEKtils' because
-[EKEventStore initWithAccessToEntityTypes:]: unrecognized selector sent to instance 0x13a59140
Interesting that this method is also mentioned and described in MacOs 10.8
but in iOS sdk it is mentioned but NOT described
Seems like apple devs forgot to "enable" it on iOS. is it possible at all or I missing something?
There's a description of the event (and some other useful information) here. You might also double-check that your UIEventKit framework is properly linked and up to date.

Resources