Hi, I have already uploaded a sqlite3 file to icloud. Now I want to download this file to my APP's Document folder. After I pressed the download button, it will show the success information. But in fact, there is no sqlite file in the documents folder or maybe the file is broken. Could someone help me?
-(IBAction)downloadPressed:(id)sender
{
if(![self downloadFileIfNotAvailable:self.icloudURL])
{
[self displayAlert:#"Warning!!" withmessage:#"failed to restore"];
}else{
[self displayAlert:#"Congratulations" withmessage:#"restore sccuessfully"];
}
}
-(BOOL)downloadFileIfNotAvailable:(NSURL *)file
{
NSNumber* isIniCloud = nil;
NSError* err;
if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) {
// If the item is in iCloud, see if it is downloaded.
if ([isIniCloud boolValue]) {
NSFileManager* fm = [NSFileManager defaultManager];
if([fm removeItemAtPath:self.filePath error:&err])
{
if (![fm startDownloadingUbiquitousItemAtURL:file error:nil]) {
return NO;
}else{
return YES;
}
}
}
return NO;
}
return NO;
}
Related
I want to upload file up to 10MB into my SQL Database. Until now I can upload small files like 0,5MB, but my point is to upload file no bigger than 10MB.
Can somebody tell me what I'm doing wrong?
My Controller:
[HttpPost]
public JsonResult UpdateJsionFile(int? id, HttpPostedFileBase file)
{
byte[] bytes;
//decimal fileSize = 100;
var supportedTypes = new[] { "txt","doc","docx","pdf", "xls", "xlsx" };
var fileExt = System.IO.Path.GetExtension(file.FileName).ToLower().Substring(1);
using (BinaryReader br = new BinaryReader(file.InputStream))
{
bytes = br.ReadBytes(file.ContentLength);
}
if(!supportedTypes.Contains(fileExt))
{
return Json(new { success = false, error = "File extention is invalid - upload only WORD/PDF/EXCEL/TXT files" }, JsonRequestBehavior.AllowGet);
}
if(file.FileName.Length>50 )
{
return Json(new { success = false, error = "File name is too long, max. 50 symbols" }, JsonRequestBehavior.AllowGet);
}
//if (file.ContentLength > (fileSize * 1024))
//{
// return Json(new { success = false, error = "File size is too big" }, JsonRequestBehavior.AllowGet);
//}
using (FileDBEntities db = new FileDBEntities())
{
tblFile f = db.tblFiles.Where(p => p.id == id).FirstOrDefault();
f.Name = Path.GetFileName(file.FileName);
f.ContentType = file.ContentType;
f.Data = bytes;
db.SaveChanges();
}
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
like I was saying, this code works perfectley with small files, but if I want to upload a "big" one(from 1 MB), I'm recieving every time message like:
function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this}
I've changed in Web.config:
<system.web>
<compilation debug="true"/>
<httpRuntime maxRequestLength="10240" />
</system.web>
it works, but not really with Json, file was uploaded but in UI i cant see it any more, at the same time a "normal" razor works...
Is there any way to check if a asset file exists in Flutter before try to load the data?
For now I have the following:
String data;
try {
data = await rootBundle
.loadString('path/to/file.json');
} catch (Exception) {
print('file not found');
}
The problem is, that I have to check for file 1, if this does not exits I have to check for a fallback file (file 2) and if this does also not exist I load a third file.
My complete code would look like this:
try{
//load file 1
} catch (..) {
//file 1 not found
//load file 2
} catch (...) {
//file 2 not found
//load file 3
}
That looks very ugly to me, but I have no better idea...
AssetBundle (as returned by rootBundle) abstracts over different ways of loading assets (local file, network) and there is no general way of checking if it exists.
You can easily wrap your loading code so that it becomes less "ugly".
Future myLoadAsset(String path) async {
try {
return await rootBundle.loadString(path);
} catch(_) {
return null;
}
}
var assetPaths = ['file1path', 'file2path', 'file3path'];
var asset;
for(var assetPath in assetPaths) {
asset = await myLoadAsset(assetPath);
if(asset != null) {
break;
}
}
if(asset == null) {
throw "Asset and fallback assets couldn't be loaded";
}
I believe a better version is the one without the need to try/catch:
import 'dart:convert';
import 'package:flutter/services.dart';
Future<bool> isLocalAsset(final String assetPath) async {
final encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(assetPath)).path);
final asset = await ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData());
return asset != null;
}
I momently developing a application with a tab bar and some navigation view controllers in Storyboard using iOS 6 and Xcode 4.5
Usually the app should support all interface orientations but I have two views that only should support portrait mode.
So I added the following code to the view controllers:
-(BOOL)shouldAutorotate
{
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
On a other app I developed without storyboard and navigation view controller on iOS 6 it works but her NOT! :/
I hope someone can help, because I found some other post that where not helpful...
With best regards from Germany
Laurenz
EDIT:
I also tried - Doesn't work! :
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
As far as I can tell, this problem arises because the UITabBarController and UINavigationController are returning their own default values for -(BOOL)shouldAutorotate and -(NSUInteger)supportedInterfaceOrientations.
One solution is to extend both of those classes via categories (or just subclass), in order to return the appropriate values from your own implementations of these methods in your view controller. This is what worked for me (you can just drop this into your App Delegate):
#implementation UITabBarController(AutorotationFromSelectedView)
- (BOOL)shouldAutorotate {
if (self.selectedViewController) {
return [self.selectedViewController shouldAutorotate];
} else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if (self.selectedViewController) {
return [self.selectedViewController supportedInterfaceOrientations];
} else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
#end
#implementation UINavigationController(AutorotationFromVisibleView)
- (BOOL)shouldAutorotate {
if (self.visibleViewController) {
return [self.visibleViewController shouldAutorotate];
} else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if (self.visibleViewController) {
return [self.visibleViewController supportedInterfaceOrientations];
} else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
#end
By default, all your view controllers will continue to autorotate. In the two View Controllers that should only support portrait mode, implement the following:
-(BOOL)shouldAutorotate {
return NO;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
Excellent answer by Jonathan.
I modified his code little bit to handle navigation controller in a single snippet.
- (BOOL)shouldAutorotate {
if (self.selectedViewController) {
if ([self.selectedViewController isKindOfClass:[UINavigationController class]]) {
return [[[(UINavigationController*)self.selectedViewController viewControllers] lastObject] shouldAutorotate];
}
return [self.selectedViewController shouldAutorotate];
} else {
return YES;
}
}
- (NSUInteger)supportedInterfaceOrientations {
if (self.selectedViewController) {
if ([self.selectedViewController isKindOfClass:[UINavigationController class]]) {
return [[[(UINavigationController*)self.selectedViewController viewControllers] lastObject] supportedInterfaceOrientations];
}
return [self.selectedViewController supportedInterfaceOrientations];
} else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
Id like to be able to track if the user shared by facebook, twitter, etc, but it seems there's no way to know which method was selected. Is there?
You can use Activity Types in setCompletionHandler
UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:nil];
[activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) {
if([activityType isEqualToString: UIActivityTypeMail]){
NSLog(#"Mail");
}
if([activityType isEqualToString: UIActivityTypePostToFacebook]){
NSLog(#"Facebook");
}
}];
[self presentViewController:activityVC animated:TRUE completion:nil];
Built-in activity types for which the system has built-in support for.
NSString *const UIActivityTypePostToFacebook;
NSString *const UIActivityTypePostToTwitter;
NSString *const UIActivityTypePostToWeibo;
NSString *const UIActivityTypeMessage;
NSString *const UIActivityTypeMail;
NSString *const UIActivityTypePrint;
NSString *const UIActivityTypeCopyToPasteboard;
NSString *const UIActivityTypeAssignToContact;
NSString *const UIActivityTypeSaveToCameraRoll;
Edited for iOS 8
Please note that this will generate a compiler warning in iOS 8, you need to use the setCompletionWithItemsHandler method instead of the setCompletionHandler method.
Replace:
[activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) {
with:
[activityVC setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
In Swift 4:
activityViewController.completionWithItemsHandler = { activity, success, items, error in
if !success{
print("cancelled")
return
}
if activity == .postToTwitter {
print("twitter")
}
if activity == .mail {
print("mail")
}
}
swift 3
let activityViewController:UIActivityViewController = UIActivityViewController(activityItems: [screenCapture], applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivityType.print, UIActivityType.postToWeibo, UIActivityType.copyToPasteboard, UIActivityType.addToReadingList, UIActivityType.postToVimeo]
activityViewController.completionWithItemsHandler = { activity, success, items, error in
if !success{
print("cancelled")
return
}
if activity == UIActivityType.postToFacebook {
print("facebook")
}
if activity == UIActivityType.mail {
print("mail")
}
}
self.present(activityViewController, animated: true, completion: nil)
You can use this lib https://github.com/rdougan/RDActivityViewController to identify which activity has been touched and return custom data by activity just by implementing its protocol.
Like This:
- (NSArray *)activityViewController:(NSArray *)activityViewController itemsForActivityType:(NSString *)activityType
{
if ([activityType isEqualToString:UIActivityTypePostToTwitter]) {
return #[#"Twitter text"];
} else if ([activityType isEqualToString:UIActivityTypeMessage]) {
return #[#"Message text"];
} else if ([activityType isEqualToString:UIActivityTypeMail]) {
return #[#"Mail text"];
} else if ([activityType isEqualToString:UIActivityTypePostToFacebook]) {
return #[#"Facebook text"];
} else {
return #[#"Default text"];
}
}
I hope I have helped you!
I've to integrated the FB SDK 3.1 in my ios application.
I successfully share an image on my wall, but i'm not able to set the "via [appname]" (it takes by default "via ios"). I've already put in my info.plist file the appid value.
I'm also not able to make the sharing work for ios5 (it replies with Error 400).
Following there's the code i use:
- (void)viewDidLoad{
appDelegate = [[UIApplication sharedApplication]delegate];
if (!appDelegate.session.isOpen) {
appDelegate.session = [[FBSession alloc] init];
if (appDelegate.session.state == FBSessionStateCreatedTokenLoaded) {
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
}];
}
}
and when i have to share, i call this method:
- (IBAction)fbShare:(id)sender {
if (appDelegate.session.isOpen) {
BOOL displayedNativeDialog = [FBNativeDialogs presentShareDialogModallyFrom:self
initialText:textView.text
image:img
url:nil
handler:nil];
if (!displayedNativeDialog) {
[self performPublishAction:^{
[FBRequestConnection startForUploadPhoto:img
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
}];
}];}
} else {
if (appDelegate.session.state != FBSessionStateCreated) {
appDelegate.session = [[FBSession alloc] init];
}
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
}];}
}
- (void) performPublishAction:(void (^)(void)) action {
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
[FBSession.activeSession reauthorizeWithPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
action();
}
else{
}
}];
} else {
action();
}}
Any hint?
Thanks a lot,
erica
I successfully share an image on my wall, but i'm not able to set the "via [appname]" (it takes by default "via ios"). I've already put in my info.plist file the appid value.
Most likely you've not set the Facebook app name. I'd recommend looking it at https://developers.facebook.com/apps admin panel