I cannot get social frameworks to function correctly on my ios device, however it functions perfectly in the iOS simulator but not on my iPad, can anyone advise on where I may have gone wrong. Thanks in advance.
- (IBAction)sharefb:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
mySLComposerSheet = [[SLComposeViewController alloc] init];
mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[mySLComposerSheet setInitialText:#"Share this app with your friends"];
[mySLComposerSheet addImage: [UIImage imageNamed:#"icon2.png"]];
[self presentViewController: mySLComposerSheet animated:
YES completion:nil];
}
[mySLComposerSheet setCompletionHandler:^
(SLComposeViewControllerResult result) {
NSString *output = [[NSString alloc] init];
switch (result) {
case SLComposeViewControllerResultCancelled:
output = #"Post Cancelled";
break;
case SLComposeViewControllerResultDone:
output = #"Posted successfully";
break;
default:
break;
}
}];
I just copy/pasted your code into a blank project and ran it on my iPad successfully, so I'm not exactly sure what the problem is but here's a couple of things you can try.
First, you use both of these lines in your code:
mySLComposerSheet = [[SLComposeViewController alloc] init];
mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
It is unnecessary, and unwise to call alloc/init on the composer right before composeViewControllerForServiceType which returns a SLComposeViewController object already. Omitting the first of those two lines could solve the problem.
Second, are you sure that "icon2.png" exists in the project? This shouldn't be causing the problem, but hey crazier things have happened.
Third, also unlikely but it is possible that you have some strange invisibles creating problems with the arguments of presentViewController due to your spacing and line break placement. Try rewriting the line to look like this:
[self presentViewController:mySLComposerSheet animated:YES completion:nil];
Site note, your NSString *output is creating a memory leak, unless it is used for something else that you haven't included in your code. This is all going off of your original post which does not actually specify the problem. If you can be more specific, I can probably be more helpful.
Related
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([HKHealthStore isHealthDataAvailable]){
NSSet *writeDataTypes = [self dataTypesToWrite];
NSSet *readDataTypes = [self dataTypesToRead];
[self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) {
NSLog(#"%s",__func__);
if (!success) {
NSLog(#"You didn't allow HealthKit to access these read/write data types. In your app, try to handle this error gracefully when a user decides not to provide access. The error was: %#. If you're using a simulator, try it on a device.", error);
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
// Update the user interface based on the current user's health information.
NSLog(#"=========================== %s",__func__);
});
}];
}
}
requestAuthorizationToShareTypes does not calling back completion method.
I had a similar issue with the permissions box not appearing and hadn't set up the HKHealthStore properly, putting this beforehand fixed it for me
self.healthStore = [[HKHealthStore alloc] init];
Here is a sample implementation that returns types instead of strings as described in the comment section.
-(NSSet*)datatypesToWrite {
NSArray *quantityTypes =
#[HKQuantityTypeIdentifierHeartRate,
HKQuantityTypeIdentifierBodyTemperature,
HKQuantityTypeIdentifierBloodPressureSystolic,
HKQuantityTypeIdentifierBloodPressureDiastolic,
HKQuantityTypeIdentifierRespiratoryRate];
NSMutableArray *hkTypes = [[NSMutableArray alloc] init];
for (NSString *identifier in quantityTypes) {
HKQuantityType *quantType =
[HKObjectType quantityTypeForIdentifier:identifier];
[hkTypes addObject:quantType];
}
// Make sure the types are of the correct style (Quantity, Category, Etc.)
HKCategoryType *catType =
[HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis];
[hkTypes addObject:catType];
return [[NSSet alloc] initWithArray:hkTypes];
}
Each time you request new types for the first time the modal permissions dialog will show up (but it won't show up again if you re-prompt for permissions not granted). Apple's guidelines are to prompt for everything you might need, but it feels a bit against best practices to me to request 12 types up front if I know somebody only asked to save into a few of them.
i am using UIActivityViewController in ios8
and using ARSafariActivity.h
NSURL *newsURL = [NSURL URLWithString:string];
NSString *newsTitle = #"..."
ARSafariActivity *safariActivity = [[ARSafariActivity alloc] init];
UIActivityViewController *avc = [[UIActivityViewController alloc]
initWithActivityItems:#[newsTitle, newsURL]
applicationActivities:#[safariActivity]];
[avc setRestorationIdentifier:#"Activity"];
[self.navigationController presentViewController:avc animated:YES completion:nil];
Everything is working properly, but when i test app in my iPhone the console show this:
LaunchServices: invalidationHandler called
How i can fix that?
Seem to be discussed/answered in several threads, e.g. here: This is a bug on Apple's side
In short - it's debug message from iOS and you should not care about it
I have done test app following this tutorial
I try to do the same without using Storyboards and it isn't work. I have enabled state preservation and restoration in AppDelegate. I have assigned restorationIdentifier to all my controllers and their views. I think i have to implement some additional code in AppDelegate to restore rootviewcontroller, but i cannot find the right way to do this.
-(BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
return YES;
}
-(BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[[StateTestFirstViewController alloc] initWithNibName:#"StateTestFirstViewController" bundle:nil] autorelease];
UIViewController *viewController2 = [[[StateTestSecondViewController alloc] initWithNibName:#"StateTestSecondViewController" bundle:nil] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.restorationIdentifier = #"TabBarController";
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Actually, your view controllers are restored between application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: so if you change your code to:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
UIViewController *viewController1 = [[[StateTestFirstViewController alloc] initWithNibName:#"StateTestFirstViewController" bundle:nil] autorelease];
UIViewController *viewController2 = [[[StateTestSecondViewController alloc] initWithNibName:#"StateTestSecondViewController" bundle:nil] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.restorationIdentifier = #"TabBarController";
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
return YES;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window makeKeyAndVisible];
return YES;
}
It worked for me. Also I recommend that you watch the WWDC 2012 Session 208 — Saving and Restoring Application State on iOS.
I had quite a few issues trying to implement this as well.
First of all, have you succeeded in making this work with storyboards?
Your code looks good and you shouldn't need anything else as there are only 2 requirements:
Set shouldRestoreApplicationState and shouldSaveApplicationState to YES in the AppDelegate
Set restoration ID's to All the UIViewControllers (UIViews don't need it)
I would suggest you pay attention to the way you "Kill" the App.
In the simulator :
Hit the simulator home button.
Stop the App with Xcode.
Play the App with Xcode.
Indeed, the system deletes your application state as soon as you kill the App from the multitask bar.
If you want it to work fine using the multitask bar, you have to set
"Application does not run in background" to YES in the Info.plist file.
Hope it helps ;)
I am maintaining some code written by someone else and when I build on Xcode 4.5 and run on iOS 6 I get this run time "error"
<Error>: The function `CGCMSUtilsGetICCProfileDataWithRenderingIntent' is obsolete and will be removed in an upcoming update. Unfortunately, this application, or a library it uses, is using this obsolete function, and is thereby contributing to an overall degradation of system performance. Please use `CGColorSpaceCopyICCProfile' instead.
when executing this code:
CGColorSpaceRef alternate = CGColorSpaceCreateDeviceRGB();
NSString *iccProfilePath = [[NSBundle mainBundle] pathForResource:#"sRGB Profile" ofType:#"icc"];
NSData *iccProfileData = [NSData dataWithContentsOfFile:iccProfilePath];
CGDataProviderRef iccProfile = CGDataProviderCreateWithCFData((CFDataRef)iccProfileData);
const CGFloat range[] = {0,1,0,1,0,1}; // min/max of the three components
CGColorSpaceRef colorSpace = CGColorSpaceCreateICCBased(3, range, iccProfile, alternate);
CGContextRef context = CGBitmapContextCreate(NULL, pageWidth, pageHeight, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
CGDataProviderRelease(iccProfile);
CGColorSpaceRelease(colorSpace);
CGColorSpaceRelease(alternate);
When I run on iOS 5.1 there is no error.
I have found that by making the following changes the error does not appear:
Change:
NSString *iccProfilePath = [[NSBundle mainBundle] pathForResource:#"sRGB Profile" ofType:#"icc"];
NSData *iccProfileData = [NSData dataWithContentsOfFile:iccProfilePath];
CGDataProviderRef iccProfile = CGDataProviderCreateWithCFData((CFDataRef)iccProfileData);
to:
char fname[]= "sRGB Profile.icc";
CGDataProviderRef iccProfile = CGDataProviderCreateWithFilename(fname);
I can't find any reference to CGDataProviderCreateWithCFData being deprecated. Can anyone explain the cause of the problem? It seems as though CGDataProviderCreateWithCFData is using CGCMSUtilsGetICCProfileDataWithRenderingIntent and CGDataProviderCreateWithFilename is using CGColorSpaceCopyICCProfile which suggests to me that CGDataProviderCreateWithCFData is deprecated. I'm not comfortable with the solution I have found because I don't understand this. Also, I hope the solution helps someone.
So, you are attaching the sRGB color profile file to the app resources and then explicitly creating a sRGB color profile at runtime on iOS. Is that needed? This document seems to suggest that the device RGB is actually the sRGB colorspace:
Apple WWDC color management talk
It would be nice if we could just call:
colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
But this does not seem to be supported on iOS either.
I'm struggling with file handling on iOS.
I could already assign my file type to iOS and I can launch my app from mail with a special file.
My app is launching and I'm firing this method:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if([url isFileURL])
{
NSString *fileConts = [[NSString alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#", url] encoding:NSUTF8StringEncoding error:nil];
[self.viewController openFile:fileConts];
fileConts = nil;
}
return YES;
}
The openFile:(NSString) method is declared in the viewController and sets the value of a textView (for now). This method works fine. I tested it via [self.viewController openFile:#"test"];.
But when my application launches with file attached, the textView keeps empty.
It seems that it doesn't adopt the string value or that it can't read the string value.
handleOpenURL will be called only if application already running (in the background).
To make sure you correctly dispatch incoming files, you also need to check it on the app launch:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
// Process url here
}
It's good idea to have 1 URL dispatcher called both from handleOpenURL and didFinishLaunchingWithOptions.
I could solve my problem.
My mistake was to initWithContentsOfFile:(NSString *)
I updated my code with
NSString *fileConts = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
Now I'm happy!
Thanks for help.