How to ask for access to photo library on startup? - xcode

I'm building an app that has the user take photos from their library to do things. I'm using X-code, and I had this code under 'didFinishLaunchingWithOptions' but keep getting an 'undeclared identifier' error. What to do?
ALAssetsLibraryGroupsEnumerationResultsBlock assetGroupEnumerator =
^(ALAssetsGroup *assetGroup, BOOL *stop) {
if (assetGroup != nil) {
// do somthing
}
};
ALAssetsLibraryAccessFailureBlock assetFailureBlock = ^(NSError *error) {
LogError(#"Error enumerating photos: %#",[error description]);
};
NSUInteger groupTypes = ALAssetsGroupAll;
[library enumerateGroupsWithTypes:groupTypes usingBlock:assetGroupEnumerator failureBlock:assetFailureBlock];

Too late an answer but you need to define library
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
or better use a class method if you are going to reuse the library for more queries
+ (ALAssetsLibrary *)defaultAssetsLibrary
{
static dispatch_once_t pred = 0;
static ALAssetsLibrary *library = nil;
dispatch_once(&pred, ^{
library = [[ALAssetsLibrary alloc] init];
});
return library;
}

Related

Facebook publish_actions deprecated

What can I do to use as an alternative to publish_actions? I have a photo app that lets users share their photos to their profile. Currently it uses logInWithPublishPermissions:#[#"publish_actions"] and then shares the files through FBSDKSharePhoto. But after August 1 this will be removed. Any thoughts? This is my current code but soon it won't work.
-(IBAction)loginToFacebook:(id)sender
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
login.loginBehavior = FBSDKLoginBehaviorWeb;
[login logInWithPublishPermissions:#[#"publish_actions"]
fromViewController:self
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(#"Process error");
} else if (result.isCancelled) {
NSLog(#"Cancelled");
nonpressTimer = [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:#selector(timeout) userInfo:nil repeats:NO];
} else {
NSLog(#"Logged in");
[self shareSegmentWithFacebookComposer];
}
}];
}
- (void)shareBoothOnFacebook {
NSUserDefaults *defaults2 = [NSUserDefaults standardUserDefaults];
NSData *data6 = [defaults2 objectForKey:#"layoutphoto"];
UIImage *myImage = [NSKeyedUnarchiver unarchiveObjectWithData:data6];
NSMutableArray *photos = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.arrSlidshowImg count]; i++) {
UIImage *image = [UIImage imageWithData:[_arrSlidshowImg objectAtIndex:i]];
FBSDKSharePhoto *photo = [[FBSDKSharePhoto alloc] init];
photo.image = image;
photo.userGenerated = YES;
[photos addObject:photo];
}
FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init];
content.photos = [photos copy];
[FBSDKShareAPI shareWithContent:content delegate:nil];
}
}
You'll need to switch to using Facebook's iOS sharing APIs which require that the Facebook Messenger app is installed. See their documentation on sharing.
You might also want to investigate the use of the iOS share sheet but that also requires the Facebook Messenger app to be installed to enable sharing to Facebook.

Copy the complete content of general NSPasteboard

I need to copy the complete content of general NSPasteboard to a pasteboard with specified name. I tried this code:
- (void)copyFromGeneralPasteboard {
NSMutableArray *archive = [[NSMutableArray alloc] init];
NSArray *typeArray = [[NSPasteboard generalPasteboard] types];
NSPasteboard *myPasteboard = [NSPasteboard pasteboardWithName:#"SpecialPb"];
[myPasteboard declareTypes:typeArray owner:self];
for (NSPasteboardItem *item in [[NSPasteboard generalPasteboard] pasteboardItems])
{
NSPasteboardItem *archivedItem = [[NSPasteboardItem alloc] init];
for (NSString *type in [item types])
{
NSData *data=[[item dataForType:type] mutableCopy];
if (data) {
[archivedItem setData:data forType:type];
}
}
[archive addObject:archivedItem];
}
[[NSPasteboard generalPasteboard] clearContents];
[myPasteboard writeObjects:archive];
[archive removeAllObjects];}
and I am using this code to check.
- (void)SendToGeneralPasteboard {
NSMutableArray *archive = [[NSMutableArray alloc] init];
for (NSPasteboardItem *item in [[NSPasteboard pasteboardWithName:#"SpecialPb"] pasteboardItems])
{
NSPasteboardItem *archivedItem = [[NSPasteboardItem alloc] init];
for (NSString *type in [item types])
{
NSData *data=[[item dataForType:type] mutableCopy];
if (data) {
[archivedItem setData:data forType:type];
}
}
[archive addObject:archivedItem];
}
[[NSPasteboard generalPasteboard] writeObjects:archive];}
So, I performed a test using IWork Pages and it works with text and attributed text. But, when I tried to run with text and image, the program just copy and paste the text. Besides, I tried to run using just image, it woks too.
Could you tell me how can I use my code with any type of data? Thanks.
I realize this is an old question, but I was working with similar stuff today so I thought I'd answer this in case anybody else is looking.
Since you're just trying to copy the complete contents from one pasteboard to another, there's no need to mess around with NSPasteboardItem. Just iterate all the typed data in one pasteboard and write it to another. Concise example in Swift:
func copyItemsFromPasteboard(_ fromPasteboard: NSPasteboard, toPasteboard: NSPasteboard) {
for thisType in fromPasteboard.types ?? [] {
let thisData = fromPasteboard.data(forType: thisType) ?? Data()
toPasteboard.setData(thisData, forType: thisType)
}
}
let generalPB = NSPasteboard(name: .generalPboard)
let customPB = NSPasteboard(name: NSPasteboard.Name(rawValue: "com.example.custom"))
copyItemsFromPasteboard(generalPB, toPasteboard: customPB)
I hope this helps somebody!

How to upload in ios app extension

How to upload using AFNetworking in ios app extension?
apple's example uses NSURLSession, can you explain to me how this works?
- (void)didSelectPost {
NSExtensionItem *imageItem = [self.extensionContext.inputItems lastObject];
// Verify that we have a valid NSExtensionItem
if (!imageItem) {
return;
}
// Verify that we have a valid NSItemProvider
NSItemProvider *imageItemProvider = [[imageItem attachments] firstObject];
if (!imageItemProvider) {
return;
}
// Look for an image inside the NSItemProvider
if ([imageItemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
[imageItemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(id item, NSError *error) {
if (item)
{
NSData *data = [NSData dataWithContentsOfURL:item];
[self method:data];
}
[self.extensionContext completeRequestReturningItems:nil completionHandler:nil];
}];
}
}
How do I upload this data using this method or using AFNetworking or using my app to upload this?
- (void)method:(NSData *)data
{
NSString *confName = #"com.example.photoblog.backgroundconfiguration";
NSURLSessionConfiguration *conf = [NSURLSessionConfiguration backgroundSessionConfiguration:confName];
NSURLSession *session = [NSURLSession sessionWithConfiguration:conf delegate:self delegateQueue:nil];
NSURLRequest *requeust = [self requestForExtensionItems];
NSURLSessionUploadTask *upload = [session uploadTaskWithStreamedRequeust:request];
[upload resume];
}
You should setting app group both Your extension and containing app,then config session like this
config.sharedContainerIdentifier = #"group.xxxxx";
You can refer more info by this tutorial
http://www.shinobicontrols.com/blog/posts/2014/07/21/ios8-day-by-day-day-2-sharing-extension

Cannot find error with SQLITE statement call

I am having a problem locating my error. The code gets through the ID(init) okay and I know the database is loading. My issue is with the IF(sqlite3_prepare_v2...) statement. When I run the code this line does not ==SQLITE_OK and it jumps to the end. ANy help is appreciated. Thanks.
#implementation CityState
static CityState *WDdatabase;
+(CityState *)WDdatabase {
if(WDdatabase == nil) {
WDdatabase = [[CityState alloc] init];
}
return WDdatabase;
}
- (id)init {
self = [super init];
if (self) {
NSString *sqliteDB = [[NSBundle mainBundle] pathForResource:#"CityAndState" ofType:#"sqlite"];
if(sqlite3_open([sqliteDB UTF8String], &WDdatebase) != SQLITE_OK){
NSLog(#"Failed to open database");
}
}
return self;
}
-(NSArray *)getAllCities {
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
NSString *query = #"SELECT * FROM Test_Table";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2(WDdatebase, [query UTF8String], -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
}
sqlite3_finalize(statement);
}
return returnArray;
}
As far as I know, Objective-C does not do static class variables as you are attempting, and the symbol WDatabase (I'm assuming the typo is just here on SO, not in your code) is actually a class identifier instead of your static variable. To implement a singleton, you will need a file-scope variable (outside of the #implementation block) (and I recommend you name it starting with an underscore to clarify when you are accessing that and when you are accessing the class method. So basically, the call you are failing is likely because you are passing a class object instead of your var. Once you have setup the static var properly.
The proper syntax then for accessing a "class variable" (which end up being just a file-scope/statically-stored variable, by virtue of Objective-C's C soul), is to send a message to the class object:
sqlite3_prepare_v2([CityState wDdatebase], [query UTF8String], ...
Further, and just to be pedantic; if you are not using any of NSString's features and only need UTF8 (or "C-style") strings, you can use them just as you would in C:
-(NSArray *)getAllCities {
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
char query[] = "SELECT * FROM Test_Table";
sqlite3_stmt *statement;
if(sqlite3_prepare_v2([CityState wDdatebase], query, -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
}
sqlite3_finalize(statement);
}
return returnArray;
}

Is it possible to airprint a fullpage UIScrollview?

I fall into this problem for a long time. as I asked, I can print the scrollview but only a part of it, not the full size view "contentView".
the code is like this:
if ([UIPrintInteractionController isPrintingAvailable])
{
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
UIGraphicsBeginImageContext(sv.contentSize);
[sv.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *myData = [NSData dataWithData:UIImagePNGRepresentation(viewImage)];
if(pic && [UIPrintInteractionController canPrintData: myData] ) {
pic.delegate =(id<UIPrintInteractionControllerDelegate>) self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [NSString stringWithFormat:#"QFTicket-%#",self.payment.id];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
pic.printInfo = printInfo;
pic.showsPageRange = YES;
pic.printingItem = myData;
pic.printFormatter=[sv viewPrintFormatter];
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(#"FAILED! due to error in domain %# with error code %u", error.domain, error.code);
}
};
[pic presentAnimated:YES completionHandler:completionHandler];
}
}
Am I missing something?
thx

Resources