I'm I obliged to pass either UIApplicationBackgroundFetchIntervalMinimum or UIApplicationBackgroundFetchIntervalNever ?
Or Is it possible to pass a custom interval instead, for example 10 minutes:
UIApplication.sharedApplication().setMinimumBackgroundFetchInterval(600.0)
In my App, I have to download some new updated data while the app is in the background.
Then I'll use the new data to send a local notification to the user.
I looked up apis and found this:
func setMinimumBackgroundFetchInterval(_ minimumBackgroundFetchInterval: NSTimeInterval)
And there is a tip for this:
The minimum number of seconds that must elapse before another
background fetch can be initiated. This value is advisory only and
does not indicate the exact amount of time expected between fetch
operations.
So I think you'd better not depend on that time interval.
Related
I use the in local notation repeatInterval, Is it possible to retrieve what time the repeatInterval will work again? I need this to update the counter "how much is left before triggering the notification".
If you're targeting iOS 10+ you should use UNUserNotificationCenter.
UNUserNotificationCenter has method getPendingNotificationRequests(completionHandler:) that will return in completion handler list of pending notification requests.
Each element of the list is UNNotificationRequest object, which contain property trigger.
If the trigger is UNTimeIntervalNotificationTrigger or UNCalendarNotificationTrigger it has method nextTriggerDate() which will give you the timepoint when it should be triggered next time.
And it looks like what are you looking for.
I'm new to CloudKit and I was trying to figure out if a Record was created by the current user. I have researched this topic and have come about two methods to do this. I'm not sure which one is right or better and I don't even quite understand how the second method works.
The first way is using the following method to get the current user and then comparing it to the user who created the record:
func fetchUserRecordID(
completionHandler: (recordID: CKRecordID?, error: CKError?) -> Void
)
The second way involves an extension on CKRecord:
extension CKRecord{
var wasCreatedByThisUser: Bool{
return (creatorUserRecordID == nil) || (creatorUserRecordID?.recordName == "__defaultOwner__")
}
}
The first method is making another call to the server to fetch an additional record. The downside is that costs time, it counts against your monthly traffic quotas, and you have yet another async callback function that your code flow will have to account for. If you wind up calling this check a lot, you would generate a lot of unnecessary traffic to the server.
The second method is checking a value, creatorUserRecordID, that came with the record you already fetched. So at the time you check its value, it's all local data, no additional calls to the server and no async processing required.
Per the answer here: creatorUserRecordID.recordName contains "__defaultOwner__" instead of UUID shown in Dashboard, __defaultOwner__ is a synonym for the local user.
The second method looks to be the better choice for most scenarios I can think of.
Is there a fast and efficient way of finding scheduled notifications? Find list of Local Notification the app has already set discusses going through the list, which is what I did:
// To avoid duplicate notifications, check whether there are already scehduled notifications with the same fireDate, reminderName and calendar name.
if let definiteDueDateComponents = reminder.dueDateComponents, definiteDueDate = definiteDueDateComponents.date, definiteScheduledNotifications = UIApplication.sharedApplication().scheduledLocalNotifications {
for notification in definiteScheduledNotifications {
if notification.fireDate?.compare(definiteDueDate) == .OrderedSame {
// Check whether there is already a notification set up for definiteDueDate?
// If so, check whether the notification is actually for the same item that I want to set up here.
}
}
}
This, however, may become inefficient, especially if I have many items that I want to check against (run the above code) before I schedule them and also if I already have various scheduled notifications.
Has anybody experimented with creating a dictionary (hash table) of scheduled notifications? If so, when do you create it and recreate it? Is it cumbersome trying to keep the hash table in synch with UIApplication.sharedApplication().scheduledLocalNotifications?
Even if you have 10000 scheduled notifications you would probably not be able to detect the amount of time it took to iterate through them with your eyes. You'd have to log the time before and after and calculate the difference, and it would likely be less than 1/1000 of a second.
This is a case of "premature optimization". Use a for loop and be done with it.
If you have more than 10000 scheduled notifications then you need to rethink your design.
I have an API code, which loads a data necessary for my application.
It's as simple as:
- (void) getDataForKey:(NSString*) key onSuccess:(id (^)())completionBlock
I cache data returned from server, so next calls of that functions should not do network request, until there is some data missing for given key, then I need to load it again from server side.
Everything was okey as long as I had one request per screen, but right now I have a case where I need to do that for every cell on one screen.
Problem is my caching doesn't work because before the response comes in from the first one, 5-6 more are created at the same time.
What could be a solution here to not create multiple network request and make other calls waiting for the first one ?
You can try to make a RequestManager class. Use dictionary to cache the requesting request.
If the next request is the same type as first one, don't make a new request but return the first one. If you choose this solution, you need to manager a completionBlock list then you will be able to send result to all requesters.
If the next request is the same type as first one, waiting in another thread until the first one done. Then make a new request, you API will read cache automatically. Your must make sure your codes are thread-safe.
Or you can use operation queues to do this. Some documents:
Apple: Operation Queues
Soheil Azarpour: How To Use NSOperations and NSOperationQueues
May be there will be so many time consuming solutions for this. I have a trick. Create a BOOL in AppDelegate, its default is FALSE. When you receive first response, then set it TRUE. So when you go to other screen and before making request just check value of your BOOL variable in if condition. If its TRUE means response received so go for it otherwise in else don't do anything.
I'm trying to implement comet style features by polling the server for changes in data and holding the connection open untill there is something to response with.
Firstly i have a static variable on my controller which stores the time that the data was last updated:
public static volatile DateTime lastUpdateTime = 0;
So whenever the data i'm polling changes this variable will be changed.
I then have an Action, which takes the last time that the data was retrieved as a parameter:
public ActionResult Push(DateTime lastViewTime)
{
while (lastUpdateTime <= lastViewTime)
{
System.Threading.Thread.Sleep(10000);
}
return Content("testing 1 2 3...");
}
So if lastUpdateTime is less than or equal to the lastViewTime, we know that there is no new data, and we simply hold the request there in a loop, keeping the connection open, untill there is new information, which we could then send back to the client, which would handle the response and then make a new request, so the connection is essentially always open.
This seems to work fine but i'm concerned about thread safety, is this OK? Does lastUpdateTime need to be marked as volatile? Is there a better way?
Thanks
edit: perhaps i should use a lock object when i update the time value
private static object lastUpdateTimeLock = new object();
..
lock (lastUpdateTimeLock)
{
lastUpdateTime = DateTime.Now;
}
Regarding your original question, you do have to be careful with DateTimes, since they're actual objects in the .NET runtime. Only a few data types can be natively accessed (eg ints, bools) without locking (assuming you're not using Interlocked). If you want to avoid any issues with Datetimes, you can get the ticks as a long and use the Interlocked class to manage them.
That said, if you're looking for comet capabilities in a .NET application, you're unfortunately going to have to go a lot further than what you've got here. IIS/ASP.NET won't scale with the approach you've got in place right now; you'll hit limits before you even get to 100 users. Among other things, you will have to switch to using async handlers, and implement a custom bounded thread pool for the incoming requests.
If you really want a tested solution for ASP.NET/IIS, check out WebSync, it's a full comet server designed specifically for that purpose.
Honestly my concern would be with the number of connections kept open and the empty while loop. The connections you're probably fine on, but I'd definitely want to do some load testing to be sure.
The while (lastUpdateTime <= lastViewTime) {} seems like it should have a Thread.Sleep(100) or something in there. Otherwise I'd think it would consume a lot of cpu cycles needlessly.
The lock does not seem necessary to me around lastUpdateTime = DateTime.Now since the previous value does not matter. If it were lastUpdateTime = lastUpdateTime + 1 or something, then maybe it would be.