#i will add more detail to the alt txt in a bit
Explore tagged Tumblr posts
Note
draw uhhh [spins wheel] Duvall and Ephrim kissing!!
what if we kissed (and we both had transformative body horror happen to us as a result of our personal convictions) (and we were both boys)
#NOW we're thinking with portals#friends at the table#meyer leopold duvall#m leopold duvall#friends at the table ephrim#prince ephrim#sangfielle#seasons of hieron#spring in hieron#my art#traditional#traditional art#sketches#pencil#mechanical pencil#i will add more detail to the alt txt in a bit#wedidthetimewarpagain#fanart#kissing#pda
33 notes
·
View notes
Text
Blog Post Template: How to Write for SEO
Writing for SEO is one of the main ways you can improve your internet presence. So, what are some of the best ways to do this?
In this blog post template, I’ll be showing you exactly how I would lay out any blog post to optimize it properly.
These are the tricks of the trade I’ve learnt over my time working as a copywriter, and now a Digital PR Manager. So, stay tuned if you want to know everything I know, so you can start boosting traffic to your blog or business…
How to Write an Introduction for SEO
We begin our blog post with an introduction, just as you’ve seen above. This introduction should start with a snippet, in bold, describing a little bit about what your blog post will entail. This should include your primary keyword/s (see below for more detail) within it, and should be exciting, to encourage people to read on.
Then, the rest of your introduction should be between two to three paragraphs long. Your paragraphs throughout your blogpost should really be no more than three sentences long. What’s more, your sentences should be no more than 25 words long, also.
Notice, above, how I’ve written the numbers two and three out in words, but not the number 25? Any number below 10 should be written in word format, and any number above, in number format!
Then, the final section of the introduction is where I write something which keeps readers reading. Something like, “to learn more about how to write the perfect SEO blogpost, read on…”.
Keyword Research
One of the most important elements of writing any blog post for SEO is using keywords. Your post should consist of:
Primary Keywords: these should be utilised within the title, based on the sorts of search queries you think people are likely to search for in Google. You can either use one main keyword, or multiple, in any blog post. Here, mine are “blog post template” and “how to write”.
Secondary Keywords: throughout your blogpost, you should also disseminate secondary keywords, which mimic your primary keywords. For example, words such as “blog post layout”, “how to write a blog post”, and the like, could make good secondary keywords in this blog post.
Emphasising Your Keywords Through Bold Text
A good way to help your search engines spots these keywords when indexing your site is by bolding these keywords. You could also bold other parts of the text you feel are important.
I’ve done this throughout this blog post layout template to show you how it’s done. Note that I also bold certain elements of bullet-point lists, too, as you can see above.
Everything You Need to Know About Subheadings
One of the most important blog layout best practices is to also make sure you use subheadings throughout. The best blog posts use an array of subheadings, and these can be formatted using the layout settings in WordPress, Google Docs, Word, or the like. For example, your blogpost could look as follows:
Title: Heading 1
Subheading: Heading 2
Subheading: Heading 2
Subheading: Heading 2
Conclusion: Heading 2
Sub-subheading: Heading 3
Sub-subheading: Heading 3
Sub-subheading: Heading 3
Sub-sub-subheading: Heading 4
Sub-subheading: Heading 3
Another very important thing to ensure is that at least one of your subheadings includes your main keyword. As you can see, I’ve added one in the conclusion, and the other in our first subheading. The more you do this throughout, the better, but remember to make it as natural as possible.
The idea behind this is to make your blogpost is readable for the user. Not only does this keep readers on your page for longer, it also means Google approves, and will value your blogpost better. Using bullet points, every so often, is also a great way to do this.
Spacing
Another important aspect of your blogpost is spacing. I like to make sure that, between every heading, paragraph, and image, there is a space. This makes it much more readable, so your audience aren’t confronted with masses and masses of text in one paragraph.
Spacing should be uniform, so ensuring all your spaces are the same text size is a must. This way, your blogpost will be much more readable, and visually appealing, for both the audience and Google.
Word Count
The ideal blogpost wordcount is between around 1200 and 1800 words. Any more than this, and your readers will probably get bored and click off. Any less than this, and Google will more likely see your blogpost as a bit of a waste of space, deeming it not valuable.
The general rule of thumb is to do your research on blog posts similar to yours, and make yours stand out. This could be done through making your blog post longer and more informative than any others that are out there.
A good tip for this is by researching the topic you’re writing on. Then, open every blog post you can find on the first page of your search engine results. From these, you can see what sort of information they provide, and create a mash up of everything you find.
Obviously, all your work should be in your own words, with your own spin on it, as plagiarism can drastically effect your SEO. But, this way, you can do your best to out-do the other posts in this search category. After all, the aim is to be the most useful article for anyone searching this query online.
Blog Post Images
Images are also really important for SEO. They break up the blogpost, which make it much more reader friendly. So, how can you master the art of disseminating images throughout a blog post?
Well, firstly, it’s important to use an image right at the start, like I’ve done above. This should then be visible, without the reader having to scroll down. Therefore, the post is instantly more visually appealing and readable.
When it comes to images, I like to ensure they’re split up evenly throughout the blog post. So, if the article is around 700 words, it may only need two images; one after the intro and one before the conclusion. Otherwise, I also like to add more throughout the blogpost somewhere, to create visual appeal, as I’ve done here.
I also like to ensure that all my images are landscape, and don’t take up too much space. This way, you don’t end up with a page full with an image when your blogpost is being viewed by a reader. This helps to ensure the reader isn’t completely bombarded by having to scroll through a bunch of images, or a huge image; they reach the next batch of next in no time.
To discover more about optimising images for SEO through alt-txt and keywords, I’ll be going into more detail in a blog post soon. This will all be included in an article about keyword research, so stay tuned for this.
Linking Throughout Your Blog Post
Throughout your blogpost, it’s super important to add links. The best way to do this is is by linking to another page of your website, for example, to a related blogpost.
For example, we could be talking about copywriting, and decide that one of our previous blogs will help. Then, we provide a link for our post within the sentence, in a natural way. So, you could say that a good way to become a copywriter is through determination… see how we’ve linked it naturally just here?
Some good sites to link are sites of factual information that we have used to source our blog facts. These includes .org sites, as well as pubmed and Google Scholar; basically, anything trustworthy. You should aim for no more than one link every 300-500 words.
How to Write a Conclusion for SEO
Finally, we finish up with an image and our final words. This shouldn’t be too long, but should just summarise what we’ve discussed, and how the reader can find out more via your website, or by getting in contact.
A good final word would be to link everything you’ve discussed in your blogpost with what your company can do with regards to this. Ultimately, it’s about creating value for the reader, and improving your business.
We should then end our conclusion with a short paragraph urging the reader to comment down below. By getting the audience engaged, you can start striking conversations, and sharing information, thus building a community for your site. You’ll see a good example of this in my conclusion, right here…
The End of Our Blog Post Template
This is everything I have learnt about optimising a blog post layout and content for SEO. I have succeeded, in a number of cases, in professionally making this work within my career. That said, having been doing this for a short time, there’s always more to learn.
SEO changes every day, which makes it a difficult art to master. By bearing in mind these principles, as well as keeping BERT in mind so that your post is human-friendly, the foundations will be there.
If you have anything to add, or have learnt something new today, drop a like or a comment below. I’d love to hear your thoughts, and whether you write your blog using SEO principles. Let SEO Company Avon, CO know, thanks for reading, and hope this helped!
0 notes
Text
Finder Sync Extension
The macOS Finder Sync Extension allows extending the Finder’s UI to show the file synchronization status. Apple’s documentation on the macOS FinderSyncExtension is good, but it lacks more info on communication between the MainApp and the Finder Sync Extension. In this article, one such example is shown as a possible solution for bidirectional communication between the two.
Creating the extension
Once you’ve created your macOS project, select the project in the project navigator and add the new target “Finder Sync Extension”.
Sandboxing
Depending on your project’s needs, you may want/need to disable the App Sandbox. If your project is going to use a virtual file system such as osxfuse, the App Sandbox needs to be disabled.
You’ll have to leave the App Sandbox enabled for the Finder Sync Extension though. Set ‘User Selected File’ permissions to None in the Finder Sync Extension. If you leave it to ‘Read Only’, which it is by default, the extension won’t be able to receive messages from the MainApp.
App groups
To be able to communicate with one another, the MainApp and the Finder Sync Extension must belong to the same App Group. Create an App Group in a pattern like: group.[app-bundle-id]
What the demo app demonstrates
The demo application consists of two components: FinderSyncExample and FinderSyncExtension. FinderSyncExample is what we call the ‘MainApp’. When started, the MainApp offers a path to a demo folder which will be created when the Set button is pressed. After successful folder creation, the app shows controls for modifying file sync statuses. Beneath the controls, there is a label showing a custom message which can be sent from the Finder extension menu.
MainApp updating file statuses in the Finder
It is possible to set a status for three files: file1.txt, file2.txt and file3.txt. Select a desired status from combo-box and tap the appropriate Set button. Observe how Finder applies sync status to the relevant file.
Finder sending message to the MainApp
On the Finder window, open the SyncExtension menu and select ‘Example Menu Item’ on it. Observe how on the MainApp window message-label is updated to show a message received from the Finder.
Multiple FinderSyncExtension instances can exist simultaneously
It is possible that more than one Finder Sync Extension is running. One Finder Sync Extension can be running in a regular Finder window. The other FinderSyncExtension process can be running in an open-file or save-document dialog. In that case, MainApp has to be able to update all FinderSyncExtension instances. Keep this in mind when designing the communication between the MainApp and the FinderSyncExtension.
Bidirectional communication
Communication between the MainApp and the FinderSyncExtension can be implemented in several ways. The concept described in this article relies on Distributed Notifications. Other options may include mach_ports, CFMessagePort or XPC. We chose Distributed Notifications because it fits with the One-application – Multiple-extensions concept.
Both the MainApp and the FinderSyncExtension processes are able to subscribe to certain messages. Delivering and receiving messages is like using the well-known NSNotificationCenter.
Sending a message from MainApp to FinderSyncExtension
To be able to receive notifications, FinderSyncExtension registers as an observer for certain notifications:
NSString* observedObject = self.mainAppBundleID; NSDistributedNotificationCenter* center = [NSDistributedNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(observingPathSet:) name:@"ObservingPathSetNotification" object:observedObject]; [center addObserver:self selector:@selector(filesStatusUpdated:) name:@"FilesStatusUpdatedNotification" object:observedObject];
The relevant code is available in the FinderCommChannel class.
For the MainApp to be able to send a message to FinderSyncExtension, use NSDistributedNotificationCenter:
NSDistributedNotificationCenter* center = [NSDistributedNotificationCenter defaultCenter]; [center postNotificationName:name object:NSBundle.mainBundle.bundleIdentifier userInfo:data deliverImmediately:YES];
More details are available in the AppCommChannel class. AppCommChannel belongs to the MainApp target. It handles sending messages to FinderSyncExtension and receiving messages from the extension. FinderCommChannel belongs to FinderSyncExtension target. It handles sending messages to the MainApp and receiving messages from the MainApp.
Throttling messages
In real-world apps, it can happen that an app wants to update the sync status of many files in a short time interval. For that reason, it may be a good idea to gather such updates and send them all in one notification. macOS will complain about sending too many notifications in a short interval. It can also give up on delivery of notifications in such cases. The AppCommChannel class shows the usage of NSTimer for throttling support. A timer checks every 250ms if there are queued updates to be delivered to FinderSyncExtension.
For a clearer display, a sequence diagram showing sending messages from the MainApp to FinderSyncExtension is given bellow.
Sending messages from FinderSyncExtension to MainApp
To send a message from FinderSync to the MainApp, NSDistributedNotificationCenter is used but in slightly different way:
- (void) send:(NSString*)name data:(NSDictionary*)data { NSDistributedNotificationCenter* center = [NSDistributedNotificationCenter defaultCenter]; NSData* jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; NSString* json = [NSString.alloc initWithData:jsonData encoding:NSUTF8StringEncoding]; [center postNotificationName:name object:json userInfo:nil deliverImmediately:YES]; }
Notice that the JSON string is sent as the object of the notification, and not in the userInfo. That is necessary for these notifications to work properly.
Restarting FinderSyncExtension on app launch
Sometimes, it may be useful to restart the extension when your MainApp is launched. To do that, execute the following code when MainApp launches (i.e. in didFinishLaunchingWithOptions method):
+ (void) restart { NSString* bundleID = NSBundle.mainBundle.bundleIdentifier; NSString* extBundleID = [NSString stringWithFormat:@"%@.FinderSyncExt", bundleID]; NSArray* apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:extBundleID]; ASTEach(apps, ^(NSRunningApplication* app) { NSString* killCommand = [NSString stringWithFormat:@"kill -s 9 %d", app.processIdentifier]; system(killCommand.UTF8String); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSString* runCommand = [NSString stringWithFormat:@"pluginkit -e use -i %@", extBundleID]; system(runCommand.UTF8String); }); }
Debugging
Debugging the FinderSyncExtension is pretty straightforward. Some options are described below.
Debugging with Xcode alone
It is possible to debug both MainApp and FinderSyncExtension simultaneously. First, start the MainApp running the Xcode target. Then, set the FinderSyncExtension scheme and run it. Set breakpoints in desired places in the MainApp source and in the FinderSyncExtension source. Sometimes, the FinderSyncExtension debug session may not be attached to the relevant process. In that case, it helps to relaunch the Finder: press Alt+Cmd+Escape to bring Force Quit Application dialog and then select the Finder and relaunch it.
Xcode should now attach the debug session properly to the new process.
Debugging with AppCode + Xcode
If you’re using AppCode, then you can launch the MainApp form AppCode and FinderSyncExtension from the Xcode. This way, you can see both logs and debug sessions a bit easier.
Troubleshooting
It could happen that, even though the MainApp and FinderSync processes are running, no file sync statuses are shown. It can also happen that the requestBadgeIdentifierForURL method is not being called at all. If that happens, check if you have other FinderSyncExtensions running on your MBP (ie Dropbox, pCloud…). You can check that in System Preferences -> Extensions -> Finder. Disable all extensions except your demo FinderSyncExtension and then see if the issue is still present.
Testing
It seems that there is not much room when it comes to testing the FinderSyncExtension. At the time of writing this post, the only way to test the extension would be to refactor the code into a framework and then have the framework tested.
Conclusion
FinderSyncExtension is a great way to show file sync statuses. Hopefully, you now have a better understanding on how to develop the extension. Solutions shown in this article are designed to be simple yet powerful enough to face real-world use cases.
Useful links
Demo project on bitbucket Finder Sync Extension FinderSync Class Human Interface Guidelines Distributed Notifications Inter-Process Communication JNWThrottledBlock – Simple throttling of blocks Open source project using mach ports for bidirectional communication
Der Beitrag Finder Sync Extension erschien zuerst auf codecentric AG Blog.
Finder Sync Extension published first on https://medium.com/@koresol
0 notes
Text
Finder Sync Extension
Finder Sync Extension allows extending Finder’s UI to show the file synchronization status. Apple’s documentation on FinderSyncExtension is good but it lacks more info on communication between MainApp and Finder Sync Extension. In this article, one such example is shown as a possible solution for bidirectional communication between the two.
Creating the extension
Once you’ve created your macOS project, select the project in Project navigator and add the new target “Finder Sync Extension”.
Sandboxing
Depending on your project’s needs, you may want/need to disable the App Sandbox. If your project is going to use virtual file system such as osxfuse, App Sandbox needs to be disabled.
You’ll have to leave App Sandbox enabled for FinderSyncExtension though. Set ‘User Selected File’ permissions to None in FinderSyncExtension. If you leave it to ‘Read Only’, which it is by default, extension won’t be able to receive messages from MainApp.
App groups
To be able to communicate with one another, MainApp and FinderSyncExtension must belong to the same App Group. Create App Group in a pattern like: group.[app-bundle-id]
What the demo app demonstrates
The demo application consists of two components: FinderSyncExample and FinderSyncExtension. FinderSyncExample is what we call the ‘MainApp’. When started, MainApp offers a path to a demo folder which will be created when the Set button is pressed. After a successful folder creation, the app shows controls for modifying file sync statuses. Beneath the controls, there is a label showing a custom message which can be sent from the Finder extension menu.
MainApp updating file statuses in Finder
It is possible to set a status for three files: file1.txt, file2.txt and file3.txt. Select a desired status from combo-box and tap the appropriate Set button. Observe how Finder applies sync status to the relevant file.
Finder sending message to MainApp
On the Finder window, open the SyncExtension menu and select ‘Example Menu Item’ on it. Observe how on the MainApp window message-label is updated to show a message received from Finder.
Multiple FinderSyncExtension instances can exist simultaneously
It is possible that more than one FinderSyncExtension is running. One FinderSyncExtension can be running in a regular Finder window. The other FinderSyncExtension process can be running in an open-file or save-document dialog. In that case, MainApp has to be able to update all FinderSyncExtension instances. Keep this in mind when designing the communication between the MainApp and the FinderSyncExtension.
Bidirectional communication
Communication between the MainApp and the FinderSyncExtension can be implemented in several ways. The concept described in this article relies on Distributed Notifications. Other options may include mach_ports, CFMessagePort or XPC. We chose Distributed Notifications because it fits with the One-application – Multiple-extensions concept.
Both the MainApp and the FinderSyncExtension processes are able to subscribe to certain messages. Delivering and receiving messages is like using the well known NSNotificationCenter.
Sending a message from MainApp to FinderSyncExtension
To be able to receive notifications, FinderSyncExtension registers as an observer for certain notifications:
NSString* observedObject = self.mainAppBundleID; NSDistributedNotificationCenter* center = [NSDistributedNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(observingPathSet:) name:@"ObservingPathSetNotification" object:observedObject]; [center addObserver:self selector:@selector(filesStatusUpdated:) name:@"FilesStatusUpdatedNotification" object:observedObject];
Relevant code is available in FinderCommChannel class.
For the MainApp to be able to send a message to FinderSyncExtension, use NSDistributedNotificationCenter:
NSDistributedNotificationCenter* center = [NSDistributedNotificationCenter defaultCenter]; [center postNotificationName:name object:NSBundle.mainBundle.bundleIdentifier userInfo:data deliverImmediately:YES];
More details are available in the AppCommChannel class. AppCommChannel belongs to the MainApp target. It handles sending messages to FinderSyncExtension and receiving messages from the extension. FinderCommChannel belongs to FinderSyncExtension target. It handles sending messages to MainApp and receiving messages from MainApp.
Throttling messages
In real world apps, it can happen that an app wants to update the sync status of many files in a short time interval. For that reason, it may be a good idea to gather such updates and send them all in one notification. macOS will complain about sending too many notifications in a short interval. It can also give up on delivery of notifications in such cases. AppCommChannel class shows usage of NSTimer for throttling support. A timer checks every 250ms if there are queued updates to be delivered to FinderSyncExtension.
For a clearer display, a sequence diagram showing sending messages from MainApp to FinderSyncExtension is given bellow.
Sending messages from FinderSyncExtension to MainApp
To send a message from FinderSync to the MainApp, NSDistributedNotificationCenter is used but in slightly different way:
- (void) send:(NSString*)name data:(NSDictionary*)data { NSDistributedNotificationCenter* center = [NSDistributedNotificationCenter defaultCenter]; NSData* jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; NSString* json = [NSString.alloc initWithData:jsonData encoding:NSUTF8StringEncoding]; [center postNotificationName:name object:json userInfo:nil deliverImmediately:YES]; }
Notice that the json string is sent as the object of the notification, and not in the userInfo. That is necessary for these notifications to work properly.
Restarting FinderSyncExtension on app launch
Sometimes, it may be useful to restart the extension when your MainApp is launched. To do that, execute the following code when MainApp launches (i.e. in didFinishLaunchingWithOptions method):
+ (void) restart { NSString* bundleID = NSBundle.mainBundle.bundleIdentifier; NSString* extBundleID = [NSString stringWithFormat:@"%@.FinderSyncExt", bundleID]; NSArray* apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:extBundleID]; ASTEach(apps, ^(NSRunningApplication* app) { NSString* killCommand = [NSString stringWithFormat:@"kill -s 9 %d", app.processIdentifier]; system(killCommand.UTF8String); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSString* runCommand = [NSString stringWithFormat:@"pluginkit -e use -i %@", extBundleID]; system(runCommand.UTF8String); }); }
Debugging
Debugging FinderSyncExtension is pretty straightforward. Some options are described below.
Debugging with Xcode alone
It is possible to debug both MainApp and FinderSyncExtension simultaneously. First, start MainApp running the Xcode target. Then, set the FinderSyncExtension scheme and run it. Set breakpoints in desired places in MainApp source and in FinderSyncExtension source. Sometimes, FinderSyncExtension debug session may not be attached to the relevant process. In that case, it helps to Relaunch Finder: press Alt+Cmd+Escape to bring Force Quit Application dialog and then select Finder and relaunch it.
Xcode should now attach the debug session properly to the new process.
Debugging with AppCode + Xcode
If you’re using AppCode, then you can launch MainApp form AppCode and FinderSyncExtension from the Xcode. This way, you can see both logs and debug sessions a bit easier.
Troubleshooting
It could happen that, even though MainApp and FinderSync processes are running, no file sync statuses are shown. It can also happen that requestBadgeIdentifierForURL method is not being called at all. If that happens, check if you have other FinderSyncExtensions running on your MBP (ie Dropbox, pCloud…). You can check that in System Preferences -> Extensions -> Finder. Disable all extensions except your demo FinderSyncExtension and then see if the issue is still present.
Testing
It seems that there is not much room when it comes to testing the FinderSyncExtension. At the time of writing this post, the only way to test the extension would be to refactor the code into a framework and then have the framework tested.
Conclusion
FinderSyncExtension is a great way to show file sync statuses. Hopefully, you now have a better understanding on how to develop the extension. Solutions shown in this article are designed to be simple yet powerful enough to face real world use cases.
Useful links
Demo project on bitbucket Finder Sync Extension FinderSync Class Human Interface Guidelines Distributed Notifications Inter-Process Communication JNWThrottledBlock – Simple throttling of blocks Open source project using mach ports for bidirectional communication
Der Beitrag Finder Sync Extension erschien zuerst auf codecentric AG Blog.
Finder Sync Extension published first on https://medium.com/@TheTruthSpy
0 notes