subscriberCellularProvider was deprecated in iOS 12.0 - objective-c

I'm trying to make a list carrier with subscriberCellularProvider. But I got one problem which is "'subscriberCellularProvider' was deprecated in iOS 12.0: Replaced by serviceSubscriberCellularProviders"
I'm using XCode 11.4.1 and iOS 13. Anybody can help me to solve this problem?

The warning is telling you that you should use CTTelephonyNetworkInfo().serviceSubscriberCellularProviders instead, that returns an optional dictionary of type [String : CTCarrier]?. Probably is added to support devices with multiple sim (eg. iPhone XR with SIM + eSIM)
I can't figure out which key to use with the dictionary, in my case (iPhone 8) I have only one object with key 0000000100000001 so I get the carrier with:
CTTelephonyNetworkInfo().serviceSubscriberCellularProviders?["0000000100000001"]
You could try with:
CTTelephonyNetworkInfo().serviceSubscriberCellularProviders?.first?.value
but obviously there’s not guarantee that you will get the same info between different executions of your app.
I couldn't find any further documentation about it

'subscriberCellularProvider' is deprecated: first deprecated in iOS 12.0
Replace 'subscriberCellularProvider' with 'serviceSubscriberCellularProviders'
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSDictionary<NSString *, CTCarrier *> *providers= [networkInfo serviceSubscriberCellularProviders];
CTCarrier *carrier = providers.allValues.firstObject;
NSString* isoCountryCode = carrier.isoCountryCode;
NSString* mobileNetworkCode = carrier.mobileNetworkCode;
NSString* mobileCountryCode = carrier.mobileCountryCode;
NSString* carrierName = carrier.carrierName;

#Andr3a88 's answer is not precise. For iPhone with 2 SIM cards CTTelephonyNetworkInfo().serviceSubscriberCellularProviders returns at least 2 elements one of them may have carrier as this
CTCarrier (0x283d8e940) {
Carrier name: [<nil>]
Mobile Country Code: [<nil>]
Mobile Network Code:[<nil>]
ISO Country Code:[<nil>]
Allows VOIP? [YES]
for non-used eSIM I guess.
So it is preferable to check if carrier name is not NIL
let netInfo = CTTelephonyNetworkInfo()
let carrier = netInfo.serviceSubscriberCellularProviders?.filter({ $0.value.carrierName != nil }).first?.value

Related

iOS 11 - Core Data - UIColor no longers works as transformable attribute

I store colours in my binary Core Data store using a transformable attribute, specifying the class of the attribute as UIColor like so:
#import "CoreDataEntity+CoreDataClass.h"
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface CoreDataEntity (CoreDataProperties)
+ (NSFetchRequest<CoreDataEntity *> *)fetchRequest;
#property (nullable, nonatomic, retain) UIColor *transformable;
#property (nullable, nonatomic, copy) NSString *string;
#end
NS_ASSUME_NONNULL_END
In the iOS 11 Beta this has stopped working with an error like this :
NSUnderlyingException=value for key 'NS.objects' was of unexpected class 'UIColor'. Allowed classes are '{(\n NSDecimalNumber,\n NSData,\n NSUUID,\n NSNumber,\n NSDate,\n NSArray,\n NSOrderedSet,\n NSDictionaryMapNode,\n NSString,\n NSSet,\n NSDictionary,\n NSURL,\n NSNull\n)}'.}";
NSUnderlyingException = "Can't read binary data from file";
}
I managed to replicate the specific problem in an XCode project on GitHub (Must be run with the XCode Beta twice to get the error).
In the demo project the store type is controlled by NSPersistentStoreDescription and setting it to NSBinaryStoreType, which I do in the AppDelegate in the exanple project, and I add objects in application didFinishLaunchingWithOptions, otherwise it's the standard template from an iOS11 app with core data. Plus a small datamodel and classes.
If you run the project twice, the first time it creates the datastore and everything is fine. The second time, the datastore tries to open and crashes the app. This problem only seems to be related to binary datastores from what I can tell, if I use an SQL backed datastore it works. However, my app is in the wild and uses binary.
I've reported it to Apple as a bug and sought help on the developer forums, but Apple has not acknowledged the bug and no help was coming.
I'm getting a bit worried as the iOS11 release date draws nearer and I have no solution, my app just won't work in iOS11.
I've tried changing the property to NSData and seeing if it was possible to just unarchive the data, but it seems it's still stored internally as a UIColor somehow and the database just won't open.
Can anyone see a workaround? I have the app in the wild, and possibly pushing out an update to convert the datastores before iOS11 could work for some, but that isn't going to guarantee all users get the fix and they could lose their data.
EDIT 1:
Radar number : 33895450
EDIT 2:
It just occured to me that this applies to any transformable attribute in core data, the values supported in the error message are just the default property types.
EDIT 3:
Just out of curiosity I filled out all the fields for the transformable attribute (it was never required before).
I added "NSKeyedUnarchiveFromData" to value transformer name of the core data entity, it should be the default, but you never know. No effect. It must be using the value transformer anyway to know that it's a UIColor.
I filled in the custom class field to be UIColor, no effect.
Edit 5 : I noticed earlier that UIColor now supports NSSecureCoding, should security somehow be the issue somehow overlooked in the other store typed.
Edit : Now that iOS is released, i’ve used one of my TSIs to further escalate this. Do i get them back if i have to use one to get them to fix their software?
Edit : Apple got back to me on my TSI, they said it’s under investigation, there is no workaround, and to wait on the bug. They refunded my TSI because they couldn’t help.
Edit 8: Same problem on macOS High Sierra, with NSColor instead of UIColor.
Apple still have not given me any feedback on my actual bug report.
Well Apple got back to me, there are new persistentStore options!
The text I got from apple:
/* Allows developers to provide an additional set of classes (which
must implement NSSecureCoding) that should be used while decoding a
binary store. Using this option is preferable to using
NSBinaryStoreInsecureDecodingCompatibilityOption.
*/ COREDATA_EXTERN NSString * const NSBinaryStoreSecureDecodingClasses
API_AVAILABLE(macosx(10.13),ios(11.0),tvos(11.0),watchos(4.0));
/* Indicate that the binary store should be decoded insecurely. This
may be necessary if a store has metadata or transformable properties
containing non-standard classes. If possible, developers should use
the NSBinaryStoreSecureDecodingClasses option to specify the contained
classes, allowing the binary store to to be securely decoded.
Applications linked before the availability date will default to using
this option.
*/ COREDATA_EXTERN NSString * const NSBinaryStoreInsecureDecodingCompatibilityOption
API_AVAILABLE(macosx(10.13),ios(11.0),tvos(11.0),watchos(4.0));
It's not immediately clear, but basically you have to supply an NSSet of classes you use as transformable attributes that comply with NSSecureCoding as an option when opening your persistent store.
An example for mine using the UIColor :
NSError *localError;
NSDictionary *options;
if (#available(iOS 11.0, *)) {
options = #{
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES,
NSBinaryStoreSecureDecodingClasses : [NSSet setWithObjects:[UIColor class], nil]
};
} else {
// Fallback on earlier versions
options = #{
NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES,
};
}
NSPersistentStore *newStore = [self.psc addPersistentStoreWithType:NSBinaryStoreType configuration:#"iOS" URL:psURL options:options error:&localError];
EDIT: Adding a solution for the newer way to open core data persistent stores using NSPersistentStoreDescription. This code is based on the current core data template.
- (NSPersistentContainer *)persistentContainer {
// The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
#synchronized (self) {
if (_persistentContainer == nil) {
NSURL *defaultURL = [NSPersistentContainer defaultDirectoryURL];
defaultURL = [defaultURL URLByAppendingPathComponent:#"CoreDataTransformableAttribBug.binary"];
_persistentContainer = [[NSPersistentContainer alloc] initWithName:#"CoreDataTransformableAttribBug"];
NSPersistentStoreDescription *desc = [NSPersistentStoreDescription persistentStoreDescriptionWithURL:defaultURL];
desc.type = NSBinaryStoreType;
if (#available(iOS 11.0, *)) {
[desc setOption:[NSSet setWithObjects:[UIColor class], nil] forKey:NSBinaryStoreSecureDecodingClasses];
}
_persistentContainer.persistentStoreDescriptions = #[desc];
[_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
if (error != nil) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
NSLog(#"Unresolved error %#, %#", error, error.userInfo);
abort();
} else {
NSLog(#"Description = %#", storeDescription);
}
}];
}
}
return _persistentContainer;
}
I also updated my gitHub project with the fix in a branch
George did all the hard work. I only applied it to Swift. Here is my solution. I put it into my NSPersistentDocument descendant.
override func configurePersistentStoreCoordinator(for url: URL, ofType fileType: String, modelConfiguration configuration: String?, storeOptions: [String : Any]? = nil) throws {
var options = storeOptions != nil ? storeOptions! : [String:Any]()
if #available(OSX 10.13, *) {
options[NSBinaryStoreSecureDecodingClasses] = NSSet(object: NSColor.self)
}
options[NSMigratePersistentStoresAutomaticallyOption] = true
options[NSInferMappingModelAutomaticallyOption] = true
try super.configurePersistentStoreCoordinator(for: url, ofType: fileType, modelConfiguration: configuration, storeOptions: options)
}
Now I can read my files again. Thanks George!

iOS 7 ANCS: Discovering the primary ANCS Service UUID

Under iOS7, is the primary ANCS Service meant to be constantly advertised, or does it need to be enabled in obfuscated settings / implemented using a custom CBPeripheralManager (using the Apple-specified Service and Characteristic UUIDs) for a potential Notification Consumer to successfully discover it and subscribe?
The Apple documentation (both the CoreBluetooth Programming Guide, and the ANCS Specification) are surprisingly bereft of any information on this. They seem to hint at requiring a custom implementation, but this is just conjecture on our part.
Given the primary ANCS Service UUID: 7905F431-B5CE-4E99-A40F-4B1E122D00D0, performing a scan yields no hits. Scanning the entire BLE spectrum, as expected, yields hits for other BLE devices, but not a single ANCS device.
EDIT 1:
Defining a custom CBPeripheralManager and manually adding the Apple-specified ANCS Service with its associated Characteristics fails, with the NSError: Error Domain=CBErrorDomain Code=8 "The specified UUID is not allowed for this operation."
Consequently, it appears that the Service UUID is reserved by Apple (as it should be), and we cannot enable it in this manner.
Any insight is greatly appreciated; we've reached out to Apple about this, and will update when we hear from them.
The code below reproduces the NSError mentioned above:
// define the ANCS Characteristics
CBUUID *notificationSourceUUID = [CBUUID UUIDWithString:#"9FBF120D-6301-42D9-8C58-25E699A21DBD"];
CBMutableCharacteristic *notificationSource = [[CBMutableCharacteristic alloc] initWithType:notificationSourceUUID properties:CBCharacteristicPropertyNotifyEncryptionRequired value:nil permissions:CBAttributePermissionsReadEncryptionRequired];
CBUUID *controlPointUUID = [CBUUID UUIDWithString:#"69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9"];
CBMutableCharacteristic *controlPoint = [[CBMutableCharacteristic alloc] initWithType:controlPointUUID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteEncryptionRequired];
CBUUID *dataSourceUUID = [CBUUID UUIDWithString:#"22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB"];
CBMutableCharacteristic *dataSource = [[CBMutableCharacteristic alloc] initWithType:dataSourceUUID properties:CBCharacteristicPropertyNotifyEncryptionRequired value:nil permissions:CBAttributePermissionsReadEncryptionRequired];
// define the ANCS Service
CBUUID *ANCSUUID = [CBUUID UUIDWithString:#"7905F431-B5CE-4E99-A40F-4B1E122D00D0"];
CBMutableService *ANCS = [[CBMutableService alloc] initWithType:ANCSUUID primary:YES];
ANCS.characteristics = #[notificationSource, controlPoint, dataSource];
// define the Advertisement data
NSMutableDictionary *advertisementData = [NSMutableDictionary dictionary];
[advertisementData setValue:#"CUSTOM_ANCS" forKey:CBAdvertisementDataLocalNameKey];
[advertisementData setValue:#"7905F431-B5CE-4E99-A40F-4B1E122D00D0" forKey:CBAdvertisementDataServiceUUIDsKey];
// publish the ANCS service
[self.peripheralManager addService:ANCS];
As a belated answer to this question, now that Mavericks is out, here is what we've come up with.
Our initial efforts to implement the ANCS specification between two iOS devices, one as Peripheral one as Central, were unsuccessful. Apple responded to us after some time (hat tip to their evangelists) and told us this was impossible.
With the addition of the CBPeripheralManager class and CBPeripheralManagerDelegate protocol to the CoreBluetooth.framework embedded in the IOBluetooth.framework on OSX Mavericks (deep breath), we can now use the BLE radio on an OSX device to implement and advertise ANCS.
Thus, this snippet belongs to a CBPeripheralManager on OSX:
- (void) advertiseANCS
{
NSLog(#"%s", __FUNCTION__);
// define the ANCS Characteristics
CBUUID *notificationSourceUUID = [CBUUID UUIDWithString:#"9FBF120D-6301-42D9-8C58-25E699A21DBD"];
CBMutableCharacteristic *notificationSource = [[CBMutableCharacteristic alloc] initWithType:notificationSourceUUID properties:CBCharacteristicPropertyNotifyEncryptionRequired value:nil permissions:CBAttributePermissionsReadEncryptionRequired];
CBUUID *controlPointUUID = [CBUUID UUIDWithString:#"69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9"];
CBMutableCharacteristic *controlPoint = [[CBMutableCharacteristic alloc] initWithType:controlPointUUID properties:CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsWriteEncryptionRequired];
CBUUID *dataSourceUUID = [CBUUID UUIDWithString:#"22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB"];
CBMutableCharacteristic *dataSource = [[CBMutableCharacteristic alloc] initWithType:dataSourceUUID properties:CBCharacteristicPropertyNotifyEncryptionRequired value:nil permissions:CBAttributePermissionsReadEncryptionRequired];
// define the ANCS Service
CBUUID *ANCSUUID = [CBUUID UUIDWithString:#"7905F431-B5CE-4E99-A40F-4B1E122D00D0"];
CBMutableService *ANCS = [[CBMutableService alloc] initWithType:ANCSUUID primary:YES];
ANCS.characteristics = #[notificationSource, controlPoint, dataSource];
// define the Advertisement data
NSMutableDictionary *advertisementData = [NSMutableDictionary dictionary];
[advertisementData setValue:#"ANCS" forKey:CBAdvertisementDataLocalNameKey];
[advertisementData setValue:#[ANCSUUID] forKey:CBAdvertisementDataServiceUUIDsKey];
// publish the ANCS service
[self.peripheralManager addService:ANCS];
[self.peripheralManager startAdvertising:advertisementData];
}
Whereas this snippet belongs on a CBCentralManager on an iOS device:
- (void) discoverANCS
{
NSLog(#"%s", __FUNCTION__);
NSMutableArray *services = [NSMutableArray array];
[services addObject:#"7905F431-B5CE-4E99-A40F-4B1E122D00D0"];
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setValue:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.centralManager scanForPeripheralsWithServices:services options:options];
}
The iOS device can now see and connect to the OSX radio, which implements the ANCS specification as detailed in the Apple documentation.
<CBCentralManager: 0x14e23280> <CBPeripheral: 0x14d27b40 identifier = 7231B80F-874E-DB5F-2AF9-7F376911E2B7, Name = "ANCS", state = disconnected> {
kCBAdvDataChannel = 39;
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = ANCS;
} -60
Happy hunting
Well the reason is because you are setting the UUID for the advertisement Data Dictionary as a String and not as a CBUUID, also I think that key takes an array of CBUUIDs.
therefore this should make it work:
NSDictionary *advertisementData = #{
CBAdvertisementDataServiceUUIDsKey:#[[CBUUID UUIDWithString:#"7905F431-B5CE-4E99-A40F-4B1E122D00D0"]],
CBAdvertisementDataLocalNameKey:#"ANCS",
};
EDIT: Oh yeah my bad! I forgot to mention that if you are trying to discover this ANCS service from another iOS Device you wont be able to see it, not under iOS 7. Somehow the OS is reserving that service to itself and wont show up on your didDiscoverServices callback even though you might be seeing it on your advertisement data. It will however, work if you have an external device, like a non-iOS device, or a pebble-like device. This is how you expose the ANCS functionality but the rest of the implementation is up to consumer of the service.
According to this blog post:
http://blog.punchthrough.com/post/63658238857/the-apple-notification-center-service-or-wtf-is
You can advertise with 'service solicitation' to pair and access the ANCS without writing any code on the iPhone!
I have not tried it, but will soon.
For anyone currently Googling a similar question: ANCS via CoreBluetooth appears to no longer work in iOS 9. Specifically,
This functionality was removed from OS X and iOS.
Neither platform can be used to consume the ANCS service anymore using CoreBluetooth.
Given by https://forums.developer.apple.com/thread/24336
The ANCS is not advertised on iOS, I used a following way to achieve a long time connection with ANCS:
My peripheral device uses a dummy service, which is advertised. An iOS application is used to discover a device with this service and to create a connection. You can write your own application, or use one of free available (like LightBlue for example).
Once a connection is established, the peripheral device enumerates all services present on connected iOS device. Beside of others, there are those three mentioned in ANCS documentation.
If your register notifications for them, you will get ANCS data.
If you bond devices (iOS and peripheral), ANCS will automatically care for connection (re)establishment any time, if it found bonded device being advertised.
I use ANCS without any code on the iPhone using "pebble-like" prototype hardware.
Using the methods documented above on this question.
The video is for a kind of joke show and meant as a joke as is the concept of "area-wide notifications" :-) and not at all technical. But might be informative somewhat.
http://www.youtube.com/watch?v=O-YWMl7IS-g
I don't make money from my youtube BTW
I have not been successful with iOS--iOS attempts.

Passing a Facebook Places id, from placesPicker in iOS... to postParams for a feed publish

This has been driving me bananas! I'm trying to get my app to publish a message to the users facebook feed, and a checkin to a facebook Place after selecting a local place from the placesPicker in iOS.
I've pretty much got everything working in testing, meaning when I just hand type string values for all the postParams for the NSMutableDictionary, it posts perfectly. ex:
self.postParams =
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
#"I am doing XYZ", #"message",
#"123456abc",#"tags",
#"123456xyz,#"place",
nil];
The above postParams work perfectly when published to feed, it displays the message, then checks in to the "place" id and says you are with the userid in "tags". The problem is that I am really getting the Place id from the Facebook SDK's placePicker. I've got the picker setup and working perfectly, but I can not figure out how to replace the hardcoded #"123456xyz" with the id from the picked Place.
this is currently what I have in there now:
self.postParams =
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
#"I am doing XYZ", #"message",
#"123456abc",#"tags",
self.selectedPlace.id,#"place",
nil];
self.selectedplace.id does successfully contain the id of the Place, when i print it with debug/NSLog in console, it is holding the value accurately. but when i try to publish this after picking a place, I get "error: domain = com.facebook.sdk, code = 5"
Here is how self.selectedPlace is defined & synthesized:
#property (strong, nonatomic) NSObject<FBGraphPlace> *selectedPlace;
...
#synthesize selectedPlace = _selectedPlace;
...
[placePicker presentModallyFromViewController:self
animated:YES
handler:^(FBViewController *sender, BOOL donePressed) {
if (donePressed) {
self.selectedPlace = placePicker.selection;
}
}];
So, to sum my question: How can I successfully get this Place id that is stored in self.selectedPlace.id into the postParams dictionary, so that it can be successfully interpreted & published to the user's feed?
Also, I should warn everyone upfront... I am self taught and still learning, and although I can look at the code, understand what it does, and write it... I'm afraid I'm not great with the terminology & discussing/understanding some of the language... lol so it would help me a great deal if you keep that in mind in any answers or comments :) Thanks, and I'm looking forward to breaking out of my stackoverflow newb shell and becoming more apart of the community here.
Figured it out... rather than setting the post params collectively with initWithObjectsAndKeys, like this:
self.postParams =
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
#"I am doing XYZ", #"message",
#"123456abc",#"tags",
self.selectedPlace.id,#"place",
nil];
Just create separate dictionaries for each param you are passing and set each one to the final postParams with setValue: forKey:
[fbPostParams setValue:self.selectedPlace.id forKey:#"place"];

Importing VCard in objective C in iPhone

I am developping an iPhone App using XCode 4.2 .in a portion of the App I will be getting a VCard as an NSString
I found this function initWithVCardRepresentation and i think it will be easier than parsing the data one by one (i.e getting the first name then the last name etc ... , but I have a hard time to implement it in my code .
I have the AddressBook and the AddressBookUI frameworks and I am trying to use this code but can t find an exact way to do it
-(IBAction)Add{
// I have a NSString *card defined somewhere else
ABAddressBookRef *iPhoneAddressBook = ABAddressBookCreate();
ABRecordRef *contact = ABPersonCreatePeopleInSourceWithVCardRepresentation(iPhoneAddressBook, (__bridge_retained CFStringRef) card);
CFRelease(contact);
CFRelease(iPhoneAddressBook);
}
when I compile ,it crashes at the line
ABRecordRef *contact = ABPersonCreatePeopleInSourceWithVCardRepresentation(iPhoneAddressBook, (__bridge_retained CFStringRef) card);
and I get the following green error in the #autoreleasepool
Thread1:Program Received Signal "SIGABRT".
I am quite new to the Apps development , please let me know if the information I gave is sufficient
Thanks
If you want to have an ABPerson afterwards (what is advisable), use:
// Assuming NSString *card exists already.
ABPerson *person = [[[ABPerson alloc] initWithVCardRepresentation:[card dataUsingEncoding:NSUTF8StringEncoding] autorelease];

Get list of installed apps on iPhone

Is there a way (some API) to get the list of installed apps on an iPhone device.
While searching for similar questions, I found some thing related to url registration, but I think there must be some API to do this, as I don't want to do any thing with the app, I just want the list.
No, apps are sandboxed and Apple-accepted APIs do not include anything that would let you do that.
You can, however, test whether a certain app is installed:
if the app is known to handle URLs of a certain type
by using [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"thisapp://foo"]
You can get a list of apps and URL schemes from here.
For jailbroken devices you can use next snipped of code:
-(void)appInstalledList
{
static NSString* const path = #"/private/var/mobile/Library/Caches/com.apple.mobile.installation.plist";
NSDictionary *cacheDict = nil;
BOOL isDir = NO;
if ([[NSFileManager defaultManager] fileExistsAtPath: path isDirectory: &isDir] && !isDir)
{
cacheDict = [NSDictionary dictionaryWithContentsOfFile: path];
NSDictionary *system = [cacheDict objectForKey: #"System"]; // First check all system (jailbroken) apps
for (NSString *key in system)
{
NSLog(#"%#",key);
}
NSDictionary *user = [cacheDict objectForKey: #"User"]; // Then all the user (App Store /var/mobile/Applications) apps
for (NSString *key in user)
{
NSLog(#"%#",key);
}
return;
}
NSLog(#"can not find installed app plist");
}
for non jailbroken device, we can use third party framework which is called "ihaspp", also its free and apple accepted. Also they given good documentation how to integrate and how to use. May be this would be helpful to you. Good luck!!
https://github.com/danielamitay/iHasApp
You could do this by using the following:
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
SEL selector = NSSelectorFromString(#"defaultWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:selector];
SEL selectorALL = NSSelectorFromString(#"allApplications");
NSMutableArray *Allapps = [workspace performSelector:selectorALL];
NSLog(#"apps: %#", Allapps);
And then by accessing each element and splitting it you can get your app name, and even the Bundle Identifier, too.
Well, not sure if this was available back when the last answer was given or not (Prior to iOS 6)
Also this one is time intensive, yet simple:
Go into settings > Gen. >usage. The first category under usage at least right now is Storage.
It will show a partial list of apps. At the bottom of this partial list is a button that says "show all apps".
Tap that and you'll have to go through screen by screen, and take screenshots (Quick lock button and home button takes a screenshot).
I'm doing this now and I have hundreds of apps on my iPhone. So it's going to take me a while. But at least at the end of the process I'll have Images of all my apps.